--- linux/fs/ext/dir.c 2018/04/24 18:12:22 1.1.1.2 +++ linux/fs/ext/dir.c 2018/04/24 18:14:21 1.1.1.3 @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -48,26 +49,24 @@ struct inode_operations ext_dir_inode_op ext_rename, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ - ext_bmap, /* bmap */ + NULL, /* bmap */ ext_truncate /* truncate */ }; static int ext_readdir(struct inode * inode, struct file * filp, struct dirent * dirent, int count) { - unsigned int block,offset,i; + unsigned int offset,i; char c; struct buffer_head * bh; struct ext_dir_entry * de; if (!inode || !S_ISDIR(inode->i_mode)) return -EBADF; -/* if (filp->f_pos & (sizeof (struct ext_dir_entry) - 1)) - return -EBADF; */ while (filp->f_pos < inode->i_size) { offset = filp->f_pos & 1023; - block = ext_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS); - if (!block || !(bh = bread(inode->i_dev, block, BLOCK_SIZE))) { + bh = ext_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0); + if (!bh) { filp->f_pos += 1024-offset; continue; } @@ -75,6 +74,13 @@ static int ext_readdir(struct inode * in while (offset < 1024 && filp->f_pos < inode->i_size) { offset += de->rec_len; filp->f_pos += de->rec_len; + if (de->rec_len < 8 || de->rec_len % 4 != 0 || + de->rec_len < de->name_len + 8) { + printk ("ext_readdir: bad directory entry\n"); + printk ("dev=%d, dir=%d, offset=%d, rec_len=%d, name_len=%d\n", + inode->i_dev, inode->i_ino, offset, de->rec_len, de->name_len); + return 0; + } if (de->inode) { for (i = 0; i < de->name_len; i++) if (c = de->name[i]) @@ -89,8 +95,8 @@ static int ext_readdir(struct inode * in return i; } } -/* de++; */ - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); + de = (struct ext_dir_entry *) ((char *) de + + de->rec_len); } brelse(bh); }