]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ext3 use-after-free bugfix
authorAndrew Morton <akpm@digeo.com>
Sat, 21 Dec 2002 09:08:07 +0000 (01:08 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sat, 21 Dec 2002 09:08:07 +0000 (01:08 -0800)
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.

fs/ext3/namei.c

index 375e90c7878e9ea7a8503bc5d1aa85666c9b665a..1abe62f73a62f5eb491a0ac8a2ac90b6375e6a52 100644 (file)
@@ -1566,8 +1566,11 @@ static int ext3_add_nondir(handle_t *handle,
 {
        int err = ext3_add_entry(handle, dentry, inode);
        if (!err) {
-               d_instantiate(dentry, inode);
-               return 0;
+               err = ext3_mark_inode_dirty(handle, inode);
+               if (!err) {
+                       d_instantiate(dentry, inode);
+                       return 0;
+               }
        }
        ext3_dec_count(handle, inode);
        iput(inode);
@@ -1609,7 +1612,6 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode)
                else
                        inode->i_mapping->a_ops = &ext3_aops;
                err = ext3_add_nondir(handle, dentry, inode);
-               ext3_mark_inode_dirty(handle, inode);
        }
        ext3_journal_stop(handle, dir);
        unlock_kernel();
@@ -1642,7 +1644,6 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
                inode->i_op = &ext3_special_inode_operations;
 #endif
                err = ext3_add_nondir(handle, dentry, inode);
-               ext3_mark_inode_dirty(handle, inode);
        }
        ext3_journal_stop(handle, dir);
        unlock_kernel();
@@ -2105,7 +2106,6 @@ static int ext3_symlink (struct inode * dir,
        }
        EXT3_I(inode)->i_disksize = inode->i_size;
        err = ext3_add_nondir(handle, dentry, inode);
-       ext3_mark_inode_dirty(handle, inode);
 out_stop:
        ext3_journal_stop(handle, dir);
        unlock_kernel();
@@ -2140,7 +2140,6 @@ static int ext3_link (struct dentry * old_dentry,
        atomic_inc(&inode->i_count);
 
        err = ext3_add_nondir(handle, dentry, inode);
-       ext3_mark_inode_dirty(handle, inode);
        ext3_journal_stop(handle, dir);
        unlock_kernel();
        return err;