Commit dd2f1160 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ext3 use-after-free bugfix

If ext3_add_nondir() fails it will do an iput() of the inode.  But we
continue to run ext3_mark_inode_dirty() against the potentially-freed
inode.  This oopses when slab poisoning is enabled.

Fix it so that we only run ext3_mark_inode_dirty() if the inode was
successfully instantiated.
parent 02d0c3df
...@@ -1565,10 +1565,13 @@ static int ext3_add_nondir(handle_t *handle, ...@@ -1565,10 +1565,13 @@ static int ext3_add_nondir(handle_t *handle,
struct dentry *dentry, struct inode *inode) struct dentry *dentry, struct inode *inode)
{ {
int err = ext3_add_entry(handle, dentry, inode); int err = ext3_add_entry(handle, dentry, inode);
if (!err) {
err = ext3_mark_inode_dirty(handle, inode);
if (!err) { if (!err) {
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
} }
}
ext3_dec_count(handle, inode); ext3_dec_count(handle, inode);
iput(inode); iput(inode);
return err; return err;
...@@ -1609,7 +1612,6 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode) ...@@ -1609,7 +1612,6 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode)
else else
inode->i_mapping->a_ops = &ext3_aops; inode->i_mapping->a_ops = &ext3_aops;
err = ext3_add_nondir(handle, dentry, inode); err = ext3_add_nondir(handle, dentry, inode);
ext3_mark_inode_dirty(handle, inode);
} }
ext3_journal_stop(handle, dir); ext3_journal_stop(handle, dir);
unlock_kernel(); unlock_kernel();
...@@ -1642,7 +1644,6 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry, ...@@ -1642,7 +1644,6 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
inode->i_op = &ext3_special_inode_operations; inode->i_op = &ext3_special_inode_operations;
#endif #endif
err = ext3_add_nondir(handle, dentry, inode); err = ext3_add_nondir(handle, dentry, inode);
ext3_mark_inode_dirty(handle, inode);
} }
ext3_journal_stop(handle, dir); ext3_journal_stop(handle, dir);
unlock_kernel(); unlock_kernel();
...@@ -2105,7 +2106,6 @@ static int ext3_symlink (struct inode * dir, ...@@ -2105,7 +2106,6 @@ static int ext3_symlink (struct inode * dir,
} }
EXT3_I(inode)->i_disksize = inode->i_size; EXT3_I(inode)->i_disksize = inode->i_size;
err = ext3_add_nondir(handle, dentry, inode); err = ext3_add_nondir(handle, dentry, inode);
ext3_mark_inode_dirty(handle, inode);
out_stop: out_stop:
ext3_journal_stop(handle, dir); ext3_journal_stop(handle, dir);
unlock_kernel(); unlock_kernel();
...@@ -2140,7 +2140,6 @@ static int ext3_link (struct dentry * old_dentry, ...@@ -2140,7 +2140,6 @@ static int ext3_link (struct dentry * old_dentry,
atomic_inc(&inode->i_count); atomic_inc(&inode->i_count);
err = ext3_add_nondir(handle, dentry, inode); err = ext3_add_nondir(handle, dentry, inode);
ext3_mark_inode_dirty(handle, inode);
ext3_journal_stop(handle, dir); ext3_journal_stop(handle, dir);
unlock_kernel(); unlock_kernel();
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