]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Have ext2 reject file handles with bad inode numbers early.
authorNeil Brown <neilb@suse.de>
Sat, 9 Sep 2006 15:44:45 +0000 (17:44 +0200)
committerAdrian Bunk <bunk@stusta.de>
Sat, 9 Sep 2006 15:44:45 +0000 (17:44 +0200)
This prevents bad inode numbers from triggering errors in
ext2_get_inode.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
fs/ext2/super.c

index cb6f9bd658de9646da588af8feacb64bbe1d3742..a8fbef73ea99991e7b6529ebb5eafe932f57ff5c 100644 (file)
@@ -253,6 +253,46 @@ static struct super_operations ext2_sops = {
 #endif
 };
 
+static struct dentry *ext2_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 != EXT2_ROOT_INO && ino < EXT2_FIRST_INO(sb))
+               return ERR_PTR(-ESTALE);
+       if (ino > le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count))
+               return ERR_PTR(-ESTALE);
+
+       /* iget isn't really right if the inode is currently unallocated!!
+        * ext2_read_inode currently does appropriate checks, but
+        * it might be "neater" to call ext2_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;
+}
+
+
 /* Yes, most of these are left as NULL!!
  * A NULL value implies the default, which works with ext2-like file
  * systems, but can be improved upon.
@@ -261,6 +301,7 @@ static struct super_operations ext2_sops = {
 struct dentry *ext2_get_parent(struct dentry *child);
 static struct export_operations ext2_export_ops = {
        .get_parent = ext2_get_parent,
+       .get_dentry = ext2_get_dentry,
 };
 
 static unsigned long get_sb_block(void **data)