diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 1e4efaf64c4b..0075e1624310 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c @@ -1849,7 +1849,12 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode, * dirent right now. Scan from the start of the block * to make sure. */ if (!inode_eq_iversion(inode, *f_version)) { - for (i = 0; i < i_size_read(inode) && i < offset; ) { + loff_t size = i_size_read(inode); + + for (i = 0; i + OCFS2_DIR_REC_LEN(1) <= size && + i < offset;) { + unsigned int rec_len; + de = (struct ocfs2_dir_entry *) (data->id_data + i); /* It's too expensive to do a full @@ -1858,10 +1863,11 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode, * least that it is non-zero. A * failure will be detected in the * dirent test below. */ - if (le16_to_cpu(de->rec_len) < - OCFS2_DIR_REC_LEN(1)) + rec_len = le16_to_cpu(de->rec_len); + if (rec_len < OCFS2_DIR_REC_LEN(1) || + i + rec_len > size) break; - i += le16_to_cpu(de->rec_len); + i += rec_len; } ctx->pos = offset = i; *f_version = inode_query_iversion(inode);