]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
jfs: fix array-index-out-of-bounds read in add_missing_indices
authorAditya Dutt <duttaditya18@gmail.com>
Tue, 1 Apr 2025 15:29:16 +0000 (20:59 +0530)
committerDave Kleikamp <dave.kleikamp@oracle.com>
Thu, 3 Apr 2025 14:11:43 +0000 (09:11 -0500)
stbl is s8 but it must contain offsets into slot which can go from 0 to
127.

Added a bound check for that error and return -EIO if the check fails.
Also make jfs_readdir return with error if add_missing_indices returns
with an error.

Reported-by: syzbot+b974bd41515f770c608b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com./bug?extid=b974bd41515f770c608b
Signed-off-by: Aditya Dutt <duttaditya18@gmail.com>
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
fs/jfs/jfs_dtree.c

index 93db6eec446556c2ec57c25e6d8dfb56b0b37247..ab11849cf9cc3c61abd3b7683f00c28503e2b670 100644 (file)
@@ -2613,7 +2613,7 @@ void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
  *          fsck.jfs should really fix this, but it currently does not.
  *          Called from jfs_readdir when bad index is detected.
  */
-static void add_missing_indices(struct inode *inode, s64 bn)
+static int add_missing_indices(struct inode *inode, s64 bn)
 {
        struct ldtentry *d;
        struct dt_lock *dtlck;
@@ -2622,7 +2622,7 @@ static void add_missing_indices(struct inode *inode, s64 bn)
        struct lv *lv;
        struct metapage *mp;
        dtpage_t *p;
-       int rc;
+       int rc = 0;
        s8 *stbl;
        tid_t tid;
        struct tlock *tlck;
@@ -2647,6 +2647,16 @@ static void add_missing_indices(struct inode *inode, s64 bn)
 
        stbl = DT_GETSTBL(p);
        for (i = 0; i < p->header.nextindex; i++) {
+               if (stbl[i] < 0) {
+                       jfs_err("jfs: add_missing_indices: Invalid stbl[%d] = %d for inode %ld, block = %lld",
+                               i, stbl[i], (long)inode->i_ino, (long long)bn);
+                       rc = -EIO;
+
+                       DT_PUTPAGE(mp);
+                       txAbort(tid, 0);
+                       goto end;
+               }
+
                d = (struct ldtentry *) &p->slot[stbl[i]];
                index = le32_to_cpu(d->index);
                if ((index < 2) || (index >= JFS_IP(inode)->next_index)) {
@@ -2664,6 +2674,7 @@ static void add_missing_indices(struct inode *inode, s64 bn)
        (void) txCommit(tid, 1, &inode, 0);
 end:
        txEnd(tid);
+       return rc;
 }
 
 /*
@@ -3017,7 +3028,8 @@ skip_one:
                }
 
                if (fix_page) {
-                       add_missing_indices(ip, bn);
+                       if ((rc = add_missing_indices(ip, bn)))
+                               goto out;
                        page_fixed = 1;
                }