Skip to content

Commit 5dff41a

Browse files
nzeckleikamp
authored andcommitted
jfs: fix array-index-out-of-bounds read in add_missing_indices
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>
1 parent a468540 commit 5dff41a

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

fs/jfs/jfs_dtree.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,7 +2613,7 @@ void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
26132613
* fsck.jfs should really fix this, but it currently does not.
26142614
* Called from jfs_readdir when bad index is detected.
26152615
*/
2616-
static void add_missing_indices(struct inode *inode, s64 bn)
2616+
static int add_missing_indices(struct inode *inode, s64 bn)
26172617
{
26182618
struct ldtentry *d;
26192619
struct dt_lock *dtlck;
@@ -2622,7 +2622,7 @@ static void add_missing_indices(struct inode *inode, s64 bn)
26222622
struct lv *lv;
26232623
struct metapage *mp;
26242624
dtpage_t *p;
2625-
int rc;
2625+
int rc = 0;
26262626
s8 *stbl;
26272627
tid_t tid;
26282628
struct tlock *tlck;
@@ -2647,6 +2647,16 @@ static void add_missing_indices(struct inode *inode, s64 bn)
26472647

26482648
stbl = DT_GETSTBL(p);
26492649
for (i = 0; i < p->header.nextindex; i++) {
2650+
if (stbl[i] < 0) {
2651+
jfs_err("jfs: add_missing_indices: Invalid stbl[%d] = %d for inode %ld, block = %lld",
2652+
i, stbl[i], (long)inode->i_ino, (long long)bn);
2653+
rc = -EIO;
2654+
2655+
DT_PUTPAGE(mp);
2656+
txAbort(tid, 0);
2657+
goto end;
2658+
}
2659+
26502660
d = (struct ldtentry *) &p->slot[stbl[i]];
26512661
index = le32_to_cpu(d->index);
26522662
if ((index < 2) || (index >= JFS_IP(inode)->next_index)) {
@@ -2664,6 +2674,7 @@ static void add_missing_indices(struct inode *inode, s64 bn)
26642674
(void) txCommit(tid, 1, &inode, 0);
26652675
end:
26662676
txEnd(tid);
2677+
return rc;
26672678
}
26682679

26692680
/*
@@ -3017,7 +3028,8 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)
30173028
}
30183029

30193030
if (fix_page) {
3020-
add_missing_indices(ip, bn);
3031+
if ((rc = add_missing_indices(ip, bn)))
3032+
goto out;
30213033
page_fixed = 1;
30223034
}
30233035

0 commit comments

Comments
 (0)