Message ID | tencent_B86ECD2ECECC92A7ED86EF92D0064A499206@qq.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | jfs: fix array-index-out-of-bounds in diNewExt | expand |
On 12/11/23 7:36PM, Edward Adam Davis wrote: > [Syz report] > UBSAN: array-index-out-of-bounds in fs/jfs/jfs_imap.c:2360:2 > index -878706688 is out of range for type 'struct iagctl[128]' > CPU: 1 PID: 5065 Comm: syz-executor282 Not tainted 6.7.0-rc4-syzkaller-00009-gbee0e7762ad2 #0 > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/10/2023 > Call Trace: > <TASK> > __dump_stack lib/dump_stack.c:88 [inline] > dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 > ubsan_epilogue lib/ubsan.c:217 [inline] > __ubsan_handle_out_of_bounds+0x11c/0x150 lib/ubsan.c:348 > diNewExt+0x3cf3/0x4000 fs/jfs/jfs_imap.c:2360 > diAllocExt fs/jfs/jfs_imap.c:1949 [inline] > diAllocAG+0xbe8/0x1e50 fs/jfs/jfs_imap.c:1666 > diAlloc+0x1d3/0x1760 fs/jfs/jfs_imap.c:1587 > ialloc+0x8f/0x900 fs/jfs/jfs_inode.c:56 > jfs_mkdir+0x1c5/0xb90 fs/jfs/namei.c:225 > vfs_mkdir+0x2f1/0x4b0 fs/namei.c:4106 > do_mkdirat+0x264/0x3a0 fs/namei.c:4129 > __do_sys_mkdir fs/namei.c:4149 [inline] > __se_sys_mkdir fs/namei.c:4147 [inline] > __x64_sys_mkdir+0x6e/0x80 fs/namei.c:4147 > do_syscall_x64 arch/x86/entry/common.c:51 [inline] > do_syscall_64+0x45/0x110 arch/x86/entry/common.c:82 > entry_SYSCALL_64_after_hwframe+0x63/0x6b > RIP: 0033:0x7fcb7e6a0b57 > Code: ff ff 77 07 31 c0 c3 0f 1f 40 00 48 c7 c2 b8 ff ff ff f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 b8 53 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 > RSP: 002b:00007ffd83023038 EFLAGS: 00000286 ORIG_RAX: 0000000000000053 > RAX: ffffffffffffffda RBX: 00000000ffffffff RCX: 00007fcb7e6a0b57 > RDX: 00000000000a1020 RSI: 00000000000001ff RDI: 0000000020000140 > RBP: 0000000020000140 R08: 0000000000000000 R09: 0000000000000000 > R10: 0000000000000000 R11: 0000000000000286 R12: 00007ffd830230d0 > R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 > > [Analysis] > When the agstart is too large, it can cause agno overflow. > > [Fix] > After obtaining agno, if the value is invalid, exit the subsequent process. Looks good. Applied. Shaggy > > Reported-and-tested-by: syzbot+553d90297e6d2f50dbc7@syzkaller.appspotmail.com > Signed-off-by: Edward Adam Davis <eadavis@qq.com> > --- > fs/jfs/jfs_imap.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c > index a037ee59e398..cc5819b3ec9a 100644 > --- a/fs/jfs/jfs_imap.c > +++ b/fs/jfs/jfs_imap.c > @@ -2179,6 +2179,9 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) > /* get the ag and iag numbers for this iag. > */ > agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); > + if (agno > MAXAG || agno < 0) > + return -EIO; > + > iagno = le32_to_cpu(iagp->iagnum); > > /* check if this is the last free extent within the
Hi Edward, kernel test robot noticed the following build warnings: https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Edward-Adam-Davis/jfs-fix-array-index-out-of-bounds-in-diNewExt/20231212-095530 base: https://github.com/kleikamp/linux-shaggy jfs-next patch link: https://lore.kernel.org/r/tencent_B86ECD2ECECC92A7ED86EF92D0064A499206%40qq.com patch subject: [PATCH] jfs: fix array-index-out-of-bounds in diNewExt config: i386-randconfig-141-20231212 (https://download.01.org/0day-ci/archive/20231214/202312142348.6HRZtXTB-lkp@intel.com/config) compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0 reproduce: (https://download.01.org/0day-ci/archive/20231214/202312142348.6HRZtXTB-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> | Closes: https://lore.kernel.org/r/202312142348.6HRZtXTB-lkp@intel.com/ New smatch warnings: fs/jfs/jfs_imap.c:2213 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 Old smatch warnings: fs/jfs/jfs_imap.c:2229 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 fs/jfs/jfs_imap.c:2304 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 fs/jfs/jfs_imap.c:2318 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 fs/jfs/jfs_imap.c:2330 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 fs/jfs/jfs_imap.c:2332 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 fs/jfs/jfs_imap.c:2363 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 fs/jfs/jfs_imap.c:2364 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 vim +2213 fs/jfs/jfs_imap.c ^1da177e4c3f41 Linus Torvalds 2005-04-16 2152 static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) ^1da177e4c3f41 Linus Torvalds 2005-04-16 2153 { ^1da177e4c3f41 Linus Torvalds 2005-04-16 2154 int agno, iagno, fwd, back, freei = 0, sword, rc; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2155 struct iag *aiagp = NULL, *biagp = NULL, *ciagp = NULL; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2156 struct metapage *amp, *bmp, *cmp, *dmp; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2157 struct inode *ipimap; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2158 s64 blkno, hint; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2159 int i, j; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2160 u32 mask; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2161 ino_t ino; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2162 struct dinode *dp; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2163 struct jfs_sb_info *sbi; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2164 ^1da177e4c3f41 Linus Torvalds 2005-04-16 2165 /* better have free extents. ^1da177e4c3f41 Linus Torvalds 2005-04-16 2166 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 2167 if (!iagp->nfreeexts) { eb8630d7d2fd13 Joe Perches 2013-06-04 2168 jfs_error(imap->im_ipimap->i_sb, "no free extents\n"); ^1da177e4c3f41 Linus Torvalds 2005-04-16 2169 return -EIO; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2170 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 2171 ^1da177e4c3f41 Linus Torvalds 2005-04-16 2172 /* get the inode map inode. ^1da177e4c3f41 Linus Torvalds 2005-04-16 2173 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 2174 ipimap = imap->im_ipimap; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2175 sbi = JFS_SBI(ipimap->i_sb); ^1da177e4c3f41 Linus Torvalds 2005-04-16 2176 ^1da177e4c3f41 Linus Torvalds 2005-04-16 2177 amp = bmp = cmp = NULL; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2178 ^1da177e4c3f41 Linus Torvalds 2005-04-16 2179 /* get the ag and iag numbers for this iag. ^1da177e4c3f41 Linus Torvalds 2005-04-16 2180 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 2181 agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); f93b91b82fcf16 Edward Adam Davis 2023-12-12 2182 if (agno > MAXAG || agno < 0) The commit introduces this agno > MAXAG comparison. But Smatch says that it should be agno >= MAXAG. f93b91b82fcf16 Edward Adam Davis 2023-12-12 2183 return -EIO; f93b91b82fcf16 Edward Adam Davis 2023-12-12 2184 ^1da177e4c3f41 Linus Torvalds 2005-04-16 2185 iagno = le32_to_cpu(iagp->iagnum); ^1da177e4c3f41 Linus Torvalds 2005-04-16 2186 ^1da177e4c3f41 Linus Torvalds 2005-04-16 2187 /* check if this is the last free extent within the ^1da177e4c3f41 Linus Torvalds 2005-04-16 2188 * iag. if so, the iag must be removed from the ag 25985edcedea63 Lucas De Marchi 2011-03-30 2189 * free extent list, so get the iags preceding and ^1da177e4c3f41 Linus Torvalds 2005-04-16 2190 * following the iag on this list. ^1da177e4c3f41 Linus Torvalds 2005-04-16 2191 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 2192 if (iagp->nfreeexts == cpu_to_le32(1)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 2193 if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 2194 if ((rc = diIAGRead(imap, fwd, &))) ^1da177e4c3f41 Linus Torvalds 2005-04-16 2195 return (rc); ^1da177e4c3f41 Linus Torvalds 2005-04-16 2196 aiagp = (struct iag *) amp->data; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2197 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 2198 ^1da177e4c3f41 Linus Torvalds 2005-04-16 2199 if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 2200 if ((rc = diIAGRead(imap, back, &bmp))) ^1da177e4c3f41 Linus Torvalds 2005-04-16 2201 goto error_out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2202 biagp = (struct iag *) bmp->data; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2203 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 2204 } else { ^1da177e4c3f41 Linus Torvalds 2005-04-16 2205 /* the iag has free extents. if all extents are free ^1da177e4c3f41 Linus Torvalds 2005-04-16 2206 * (as is the case for a newly allocated iag), the iag ^1da177e4c3f41 Linus Torvalds 2005-04-16 2207 * must be added to the ag free extent list, so get ^1da177e4c3f41 Linus Torvalds 2005-04-16 2208 * the iag at the head of the list in preparation for ^1da177e4c3f41 Linus Torvalds 2005-04-16 2209 * adding this iag to this list. ^1da177e4c3f41 Linus Torvalds 2005-04-16 2210 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 2211 fwd = back = -1; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2212 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 @2213 if ((fwd = imap->im_agctl[agno].extfree) >= 0) { If agno == MAXAG then we're out of bounds here. ^1da177e4c3f41 Linus Torvalds 2005-04-16 2214 if ((rc = diIAGRead(imap, fwd, &))) ^1da177e4c3f41 Linus Torvalds 2005-04-16 2215 goto error_out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2216 aiagp = (struct iag *) amp->data; ^1da177e4c3f41 Linus Torvalds 2005-04-16 2217 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 2218 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 2219 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 2220 ^1da177e4c3f41 Linus Torvalds 2005-04-16 2221 /* check if the iag has no free inodes. if so, the iag
On 1/2/24 7:29AM, Dan Carpenter wrote: > Hi Edward, > > kernel test robot noticed the following build warnings: > > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > url: https://github.com/intel-lab-lkp/linux/commits/Edward-Adam-Davis/jfs-fix-array-index-out-of-bounds-in-diNewExt/20231212-095530 > base: https://github.com/kleikamp/linux-shaggy jfs-next > patch link: https://lore.kernel.org/r/tencent_B86ECD2ECECC92A7ED86EF92D0064A499206%40qq.com > patch subject: [PATCH] jfs: fix array-index-out-of-bounds in diNewExt > config: i386-randconfig-141-20231212 (https://download.01.org/0day-ci/archive/20231214/202312142348.6HRZtXTB-lkp@intel.com/config) > compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0 > reproduce: (https://download.01.org/0day-ci/archive/20231214/202312142348.6HRZtXTB-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> > | Closes: https://lore.kernel.org/r/202312142348.6HRZtXTB-lkp@intel.com/ I modified Edward's patch in the jfs-next branch with the corrected test. Thanks for catching this. Shaggy > > New smatch warnings: > fs/jfs/jfs_imap.c:2213 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 > > Old smatch warnings: > fs/jfs/jfs_imap.c:2229 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 > fs/jfs/jfs_imap.c:2304 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 > fs/jfs/jfs_imap.c:2318 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 > fs/jfs/jfs_imap.c:2330 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 > fs/jfs/jfs_imap.c:2332 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 > fs/jfs/jfs_imap.c:2363 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 > fs/jfs/jfs_imap.c:2364 diNewExt() error: buffer overflow 'imap->im_imap.in_agctl' 128 <= 128 > > vim +2213 fs/jfs/jfs_imap.c > > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2152 static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2153 { > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2154 int agno, iagno, fwd, back, freei = 0, sword, rc; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2155 struct iag *aiagp = NULL, *biagp = NULL, *ciagp = NULL; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2156 struct metapage *amp, *bmp, *cmp, *dmp; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2157 struct inode *ipimap; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2158 s64 blkno, hint; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2159 int i, j; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2160 u32 mask; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2161 ino_t ino; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2162 struct dinode *dp; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2163 struct jfs_sb_info *sbi; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2164 > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2165 /* better have free extents. > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2166 */ > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2167 if (!iagp->nfreeexts) { > eb8630d7d2fd13 Joe Perches 2013-06-04 2168 jfs_error(imap->im_ipimap->i_sb, "no free extents\n"); > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2169 return -EIO; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2170 } > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2171 > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2172 /* get the inode map inode. > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2173 */ > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2174 ipimap = imap->im_ipimap; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2175 sbi = JFS_SBI(ipimap->i_sb); > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2176 > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2177 amp = bmp = cmp = NULL; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2178 > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2179 /* get the ag and iag numbers for this iag. > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2180 */ > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2181 agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); > f93b91b82fcf16 Edward Adam Davis 2023-12-12 2182 if (agno > MAXAG || agno < 0) > > The commit introduces this agno > MAXAG comparison. But Smatch says > that it should be agno >= MAXAG. > > f93b91b82fcf16 Edward Adam Davis 2023-12-12 2183 return -EIO; > f93b91b82fcf16 Edward Adam Davis 2023-12-12 2184 > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2185 iagno = le32_to_cpu(iagp->iagnum); > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2186 > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2187 /* check if this is the last free extent within the > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2188 * iag. if so, the iag must be removed from the ag > 25985edcedea63 Lucas De Marchi 2011-03-30 2189 * free extent list, so get the iags preceding and > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2190 * following the iag on this list. > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2191 */ > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2192 if (iagp->nfreeexts == cpu_to_le32(1)) { > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2193 if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) { > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2194 if ((rc = diIAGRead(imap, fwd, &))) > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2195 return (rc); > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2196 aiagp = (struct iag *) amp->data; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2197 } > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2198 > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2199 if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) { > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2200 if ((rc = diIAGRead(imap, back, &bmp))) > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2201 goto error_out; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2202 biagp = (struct iag *) bmp->data; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2203 } > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2204 } else { > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2205 /* the iag has free extents. if all extents are free > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2206 * (as is the case for a newly allocated iag), the iag > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2207 * must be added to the ag free extent list, so get > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2208 * the iag at the head of the list in preparation for > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2209 * adding this iag to this list. > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2210 */ > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2211 fwd = back = -1; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2212 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { > ^1da177e4c3f41 Linus Torvalds 2005-04-16 @2213 if ((fwd = imap->im_agctl[agno].extfree) >= 0) { > > If agno == MAXAG then we're out of bounds here. > > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2214 if ((rc = diIAGRead(imap, fwd, &))) > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2215 goto error_out; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2216 aiagp = (struct iag *) amp->data; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2217 } > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2218 } > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2219 } > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2220 > ^1da177e4c3f41 Linus Torvalds 2005-04-16 2221 /* check if the iag has no free inodes. if so, the iag >
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index a037ee59e398..cc5819b3ec9a 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -2179,6 +2179,9 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) /* get the ag and iag numbers for this iag. */ agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); + if (agno > MAXAG || agno < 0) + return -EIO; + iagno = le32_to_cpu(iagp->iagnum); /* check if this is the last free extent within the
[Syz report] UBSAN: array-index-out-of-bounds in fs/jfs/jfs_imap.c:2360:2 index -878706688 is out of range for type 'struct iagctl[128]' CPU: 1 PID: 5065 Comm: syz-executor282 Not tainted 6.7.0-rc4-syzkaller-00009-gbee0e7762ad2 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/10/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 ubsan_epilogue lib/ubsan.c:217 [inline] __ubsan_handle_out_of_bounds+0x11c/0x150 lib/ubsan.c:348 diNewExt+0x3cf3/0x4000 fs/jfs/jfs_imap.c:2360 diAllocExt fs/jfs/jfs_imap.c:1949 [inline] diAllocAG+0xbe8/0x1e50 fs/jfs/jfs_imap.c:1666 diAlloc+0x1d3/0x1760 fs/jfs/jfs_imap.c:1587 ialloc+0x8f/0x900 fs/jfs/jfs_inode.c:56 jfs_mkdir+0x1c5/0xb90 fs/jfs/namei.c:225 vfs_mkdir+0x2f1/0x4b0 fs/namei.c:4106 do_mkdirat+0x264/0x3a0 fs/namei.c:4129 __do_sys_mkdir fs/namei.c:4149 [inline] __se_sys_mkdir fs/namei.c:4147 [inline] __x64_sys_mkdir+0x6e/0x80 fs/namei.c:4147 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7fcb7e6a0b57 Code: ff ff 77 07 31 c0 c3 0f 1f 40 00 48 c7 c2 b8 ff ff ff f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 b8 53 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffd83023038 EFLAGS: 00000286 ORIG_RAX: 0000000000000053 RAX: ffffffffffffffda RBX: 00000000ffffffff RCX: 00007fcb7e6a0b57 RDX: 00000000000a1020 RSI: 00000000000001ff RDI: 0000000020000140 RBP: 0000000020000140 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000286 R12: 00007ffd830230d0 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [Analysis] When the agstart is too large, it can cause agno overflow. [Fix] After obtaining agno, if the value is invalid, exit the subsequent process. Reported-and-tested-by: syzbot+553d90297e6d2f50dbc7@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis <eadavis@qq.com> --- fs/jfs/jfs_imap.c | 3 +++ 1 file changed, 3 insertions(+)