]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ocfs2: add boundary check to ocfs2_check_dir_entry()
authorDmitry Antipov <dmantipov@yandex.ru>
Mon, 13 Oct 2025 06:28:26 +0000 (09:28 +0300)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 12 Nov 2025 18:00:16 +0000 (10:00 -0800)
In 'ocfs2_check_dir_entry()', add extra check whether at least the
smallest possible dirent may be located at the specified offset within
bh's data, thus preventing an out-of-bounds accesses below.

Link: https://lkml.kernel.org/r/20251013062826.122586-1-dmantipov@yandex.ru
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Reported-by: syzbot+b20bbf680bb0f2ecedae@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b20bbf680bb0f2ecedae
Reviewed-by: Heming Zhao <heming.zhao@suse.com>
Cc: Joseph Qi <jiangqi903@gmail.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/ocfs2/dir.c

index dc3d66263335de147ea50247d288d1d6588a5894..2785ff245e79e47bf5329089af455c63cdc6a40c 100644 (file)
@@ -302,8 +302,21 @@ 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, "directory entry (#%llu: offset=%lu) "
+                    "too close to end or out-of-bounds",
+                    (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";