Commit 6c2155b9 authored by Djalal Harouni's avatar Djalal Harouni Committed by Jan Kara

ext{3,4}: Fix potential race when setversion ioctl updates inode

The EXT{3,4}_IOC_SETVERSION ioctl() updates i_ctime and i_generation
without i_mutex. This can lead to a race with the other operations that
update i_ctime. This is not a big issue but let's make the ioctl consistent
with how we handle e.g. other timestamp updates and use i_mutex to protect
inode changes.
Signed-off-by: default avatarDjalal Harouni <tixxdz@opendz.org>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 853a0c25
...@@ -134,10 +134,11 @@ long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -134,10 +134,11 @@ long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
goto setversion_out; goto setversion_out;
} }
mutex_lock(&inode->i_mutex);
handle = ext3_journal_start(inode, 1); handle = ext3_journal_start(inode, 1);
if (IS_ERR(handle)) { if (IS_ERR(handle)) {
err = PTR_ERR(handle); err = PTR_ERR(handle);
goto setversion_out; goto unlock_out;
} }
err = ext3_reserve_inode_write(handle, inode, &iloc); err = ext3_reserve_inode_write(handle, inode, &iloc);
if (err == 0) { if (err == 0) {
...@@ -146,6 +147,9 @@ long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -146,6 +147,9 @@ long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
err = ext3_mark_iloc_dirty(handle, inode, &iloc); err = ext3_mark_iloc_dirty(handle, inode, &iloc);
} }
ext3_journal_stop(handle); ext3_journal_stop(handle);
unlock_out:
mutex_unlock(&inode->i_mutex);
setversion_out: setversion_out:
mnt_drop_write(filp->f_path.mnt); mnt_drop_write(filp->f_path.mnt);
return err; return err;
......
...@@ -158,10 +158,11 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -158,10 +158,11 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
goto setversion_out; goto setversion_out;
} }
mutex_lock(&inode->i_mutex);
handle = ext4_journal_start(inode, 1); handle = ext4_journal_start(inode, 1);
if (IS_ERR(handle)) { if (IS_ERR(handle)) {
err = PTR_ERR(handle); err = PTR_ERR(handle);
goto setversion_out; goto unlock_out;
} }
err = ext4_reserve_inode_write(handle, inode, &iloc); err = ext4_reserve_inode_write(handle, inode, &iloc);
if (err == 0) { if (err == 0) {
...@@ -170,6 +171,9 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -170,6 +171,9 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
err = ext4_mark_iloc_dirty(handle, inode, &iloc); err = ext4_mark_iloc_dirty(handle, inode, &iloc);
} }
ext4_journal_stop(handle); ext4_journal_stop(handle);
unlock_out:
mutex_unlock(&inode->i_mutex);
setversion_out: setversion_out:
mnt_drop_write(filp->f_path.mnt); mnt_drop_write(filp->f_path.mnt);
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment