diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index ece0462a5d26..3384be2ef49a 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c @@ -302,8 +302,20 @@ static int ocfs2_check_dir_entry(struct inode *dir, unsigned long offset) { const char *error_msg = NULL; - const int rlen = le16_to_cpu(de->rec_len); - const unsigned long next_offset = ((char *) de - buf) + rlen; + unsigned long next_offset; + int rlen; + + if (offset > size - OCFS2_DIR_REC_LEN(1)) { + /* Dirent is (maybe partially) beyond the buffer + boundaries so touching 'de' members is unsafe. */ + mlog(ML_ERROR, "out-of-bounds entry in directory #%llu: " + "offset=%lu", (unsigned long long)OCFS2_I(dir)->ip_blkno, + offset); + return 0; + } + + rlen = le16_to_cpu(de->rec_len); + next_offset = ((char *) de - buf) + rlen; if (unlikely(rlen < OCFS2_DIR_REC_LEN(1))) error_msg = "rec_len is smaller than minimal";