]> git.itanic.dy.fi Git - linux-stable/commitdiff
Have ext3 reject file handles with bad inode numbers early
authorEric Sandeen <esandeen@redhat.com>
Fri, 4 Aug 2006 15:35:34 +0000 (10:35 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 23 Aug 2006 21:13:30 +0000 (14:13 -0700)
blatantly ripped off from Neil Brown's ext2 patch.

Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Acked-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/ext3/super.c

index f8a5266ea1ffed333fd8b9c92af9a4da14518eb4..86534ad79341afa26d0e01e24e1779f0b4b27052 100644 (file)
@@ -620,8 +620,48 @@ static struct super_operations ext3_sops = {
 #endif
 };
 
+static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp)
+{
+       __u32 *objp = vobjp;
+       unsigned long ino = objp[0];
+       __u32 generation = objp[1];
+       struct inode *inode;
+       struct dentry *result;
+
+       if (ino != EXT3_ROOT_INO && ino < EXT3_FIRST_INO(sb))
+               return ERR_PTR(-ESTALE);
+       if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count))
+               return ERR_PTR(-ESTALE);
+
+       /* iget isn't really right if the inode is currently unallocated!!
+        * ext3_read_inode currently does appropriate checks, but
+        * it might be "neater" to call ext3_get_inode first and check
+        * if the inode is valid.....
+        */
+       inode = iget(sb, ino);
+       if (inode == NULL)
+               return ERR_PTR(-ENOMEM);
+       if (is_bad_inode(inode)
+           || (generation && inode->i_generation != generation)
+               ) {
+               /* we didn't find the right inode.. */
+               iput(inode);
+               return ERR_PTR(-ESTALE);
+       }
+       /* now to find a dentry.
+        * If possible, get a well-connected one
+        */
+       result = d_alloc_anon(inode);
+       if (!result) {
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
+       return result;
+}
+
 static struct export_operations ext3_export_ops = {
        .get_parent = ext3_get_parent,
+       .get_dentry = ext3_get_dentry,
 };
 
 enum {