Created attachment 228539 [details] An ext3 disk image that causes ext2_search_dirblock() to loop forever. The code in ext2_search_dirblock() that handles e2d_reclen == 0 doesn't increment ep, and thus loops forever. I've attached a demo: % gunzip ext34.img.gz % sudo mdconfig -f ext34.img % sudo mount -t ext2fs -o ro /dev/md0 /mnt % sudo cp /mnt/a /dev/null <the lookup never finishes> FreeBSD unmatched 14.0-CURRENT FreeBSD 14.0-CURRENT #0 main-n249571-b5f90655ea3: Thu Sep 23 06:10:05 UTC 2021 root@releng1.nyi.freebsd.org:/usr/obj/usr/src/riscv.riscv64/sys/GENERIC riscv
Hi, Robert. Thanks a lot for reports and images for reproduction. I successfully reproduced current issue on amd64 with crash instead of infinity loop: #14 0xffffffff810f1927 in trap (frame=0xfffffe00af5eb7b0) at /usr/src/sys/amd64/amd64/trap.c:443 #15 <signal handler called> #16 ext2_search_dirblock (ip=<optimized out>, ip@entry=0xfffff80004d73900, data=<optimized out>, foundp=foundp@entry=0xfffffe00af5eb990, name=0xfffff80004c87805 "a", namelen=1, entryoffsetinblockp=<optimized out>, entryoffsetinblockp@entry=0xfffffe00af5eb9dc, offp=0xfffffe00af5eb9e4, prevoffp=0xfffffe00af5eb9ac, endusefulp=0xfffffe00af5eb9d4, ssp=0xfffffe00af5eb978) at /usr/src/sys/fs/ext2fs/ext2_lookup.c:743 #17 0xffffffff82746852 in ext2_lookup_ino (vdp=<optimized out>, vpp=0xfffffe00af5ebc28, cnp=0xfffffe00af5ebc50, dd_ino=0x0) at /usr/src/sys/fs/ext2fs/ext2_lookup.c:455 #18 0xffffffff80cf9f16 in VOP_CACHEDLOOKUP (dvp=0xfffff800b50d3700, vpp=0xfffffe00af5ebc28, cnp=0xfffffe00af5ebc50) at ./vnode_if.h:103 #19 vfs_cache_lookup (ap=<optimized out>) at /usr/src/sys/kern/vfs_cache.c:3068 #20 0xffffffff80d0b1e1 in VOP_LOOKUP (dvp=0xfffff800b50d3700, vpp=0xfffffe00af5ebc28, cnp=0xfffffe00af5ebc50) at ./vnode_if.h:69 #21 lookup (ndp=ndp@entry=0xfffffe00af5ebbd0) at /usr/src/sys/kern/vfs_lookup.c:1128 --Type <RET> for more, q to quit, c to continue without paging-- #22 0xffffffff80d0a0de in namei (ndp=ndp@entry=0xfffffe00af5ebbd0) at /usr/src/sys/kern/vfs_lookup.c:658 #23 0xffffffff80d29ba2 in kern_statat (td=0xfffffe0094b47e40, flag=<optimized out>, fd=-100, path=0x8018182f8 <error: Cannot access memory at address 0x8018182f8>, pathseg=pathseg@entry=UIO_USERSPACE, sbp=sbp@entry=0xfffffe00af5ebd18, hook=0x0) at /usr/src/sys/kern/vfs_syscalls.c:2441 Issues 259105, 259107, 259112 were successfully reproduced too. The problem with these sort of issues, I mean malicious images with bad/corrupted metadata, that it is too difficult to make crosscheck of metadata values read from disk. The only way to avoid it, is to format drive with ext4 metadata_csum (RO_COMPAT_METADATA_CSUM) feature turned on. Need to find a way, how the metadata values, which cause a crashes, could be verified.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=bb9f1ba4b55c1f566d59cc7c7d1d28dd37715984 commit bb9f1ba4b55c1f566d59cc7c7d1d28dd37715984 Author: Fedor Uporov <fsu@FreeBSD.org> AuthorDate: 2021-10-29 12:45:50 +0000 Commit: Fedor Uporov <fsu@FreeBSD.org> CommitDate: 2021-12-30 06:14:44 +0000 Add more accurate directory entries check Rename ext2_dirbadentry() to ext2_check_direntry(). Add directory entry inode value check, and call ext2_check_direntry() in all cases. The dirchk sysctl is removed. PR: 259024,259041 Reported by: Robert Morris Reviewed by: pfg MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D33374 sys/fs/ext2fs/ext2_lookup.c | 39 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 29 deletions(-)