]> git.karo-electronics.de Git - linux-beck.git/blobdiff - fs/fat/inode.c
fat: add simple validation for directory inode
[linux-beck.git] / fs / fat / inode.c
index 3ac9078fde65f87ef3b434d21af0cb78211f3953..08ef5fd0d5029326430b76f0b28d34d7cd52255f 100644 (file)
@@ -449,6 +449,24 @@ static int fat_calc_dir_size(struct inode *inode)
        return 0;
 }
 
+static int fat_validate_dir(struct inode *dir)
+{
+       struct super_block *sb = dir->i_sb;
+
+       if (dir->i_nlink < 2) {
+               /* Directory should have "."/".." entries at least. */
+               fat_fs_error(sb, "corrupted directory (invalid entries)");
+               return -EIO;
+       }
+       if (MSDOS_I(dir)->i_start == 0 ||
+           MSDOS_I(dir)->i_start == MSDOS_SB(sb)->root_cluster) {
+               /* Directory should point valid cluster. */
+               fat_fs_error(sb, "corrupted directory (invalid i_start)");
+               return -EIO;
+       }
+       return 0;
+}
+
 /* doesn't deal with root inode */
 int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
 {
@@ -475,6 +493,10 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
                MSDOS_I(inode)->mmu_private = inode->i_size;
 
                set_nlink(inode, fat_subdirs(inode));
+
+               error = fat_validate_dir(inode);
+               if (error < 0)
+                       return error;
        } else { /* not a directory */
                inode->i_generation |= 1;
                inode->i_mode = fat_make_mode(sbi, de->attr,