[PATCH experimental-tests] erofs-utils: tests: test FUSE error handling on corrupted inodes
Gao Xiang
hsiangkao at linux.alibaba.com
Mon Mar 30 16:43:12 AEDT 2026
On 2026/3/30 12:28, Nithurshen wrote:
> This patch introduces a regression test (erofs/099) to verify that
> the FUSE daemon gracefully handles corrupted inodes without crashing
> or violating the FUSE protocol.
>
> Recently, a bug was identified where erofs_read_inode_from_disk()
> would fail, but erofsfuse_getattr() lacked a return statement
> after sending an error reply. This caused a fall-through, sending
> a second reply via fuse_reply_attr() and triggering a libfuse
> segmentation fault.
>
> To prevent future regressions, this test:
> 1. Creates a valid EROFS image.
> 2. Surgically corrupts the root inode (injecting random data at
> offset 1152) while leaving the superblock intact so it mounts.
> 3. Mounts the image in the foreground to capture daemon stderr.
> 4. Runs 'stat' to trigger the inode read failure.
> 5. Evaluates the stderr log to ensure no segfaults, aborts, or
> "multiple replies" warnings are emitted by libfuse.
>
> Signed-off-by: Nithurshen <nithurshen.dev at gmail.com>
> ---
> tests/Makefile.am | 3 ++
> tests/erofs/099 | 76 +++++++++++++++++++++++++++++++++++++++++++++
> tests/erofs/099.out | 2 ++
> 3 files changed, 81 insertions(+)
> create mode 100755 tests/erofs/099
> create mode 100644 tests/erofs/099.out
>
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index e376d6a..c0f117c 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -122,6 +122,9 @@ TESTS += erofs/027
> # 028 - test inode page cache sharing functionality
> TESTS += erofs/028
>
> +# 099 - test fuse error handling on truncated images
> +TESTS += erofs/099
> +
> EXTRA_DIST = common/rc erofs
>
> clean-local: clean-local-check
> diff --git a/tests/erofs/099 b/tests/erofs/099
> new file mode 100755
> index 0000000..952bdbd
> --- /dev/null
> +++ b/tests/erofs/099
> @@ -0,0 +1,76 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Test FUSE daemon error handling on corrupted inodes (missing return fix)
> +#
> +seq=`basename $0`
> +seqres=$RESULT_DIR/$(echo $0 | awk '{print $((NF-1))"/"$NF}' FS="/")
> +
> +# get standard environment, filters and checks
> +. "${srcdir}/common/rc"
> +
> +cleanup()
> +{
> + cd /
> + rm -rf $tmp.*
> + # Ensure we kill our background daemon if it's still alive
> + [ -n "$fuse_pid" ] && kill -9 $fuse_pid 2>/dev/null
> +}
> +
> +# remove previous $seqres.full before test
> +rm -f $seqres.full
> +
> +# real QA test starts here
> +echo "QA output created by $seq"
> +
> +[ -z "$EROFSFUSE_PROG" ] && _notrun "erofsfuse is not available"
> +
> +if [ -z $SCRATCH_DEV ]; then
> + SCRATCH_DEV=$tmp/erofs_$seq.img
> + rm -f SCRATCH_DEV
> +fi
> +
> +localdir="$tmp/$seq"
> +rm -rf $localdir
> +mkdir -p $localdir
> +
> +echo "test data" > $localdir/testfile
> +
> +_scratch_mkfs $localdir >> $seqres.full 2>&1 || _fail "failed to mkfs"
> +
> +# Corrupt the root inode to force erofs_read_inode_from_disk to fail.
> +dd if=/dev/urandom of=$SCRATCH_DEV bs=1 seek=1152 count=1024 conv=notrunc >> $seqres.full 2>&1
> +
> +# Bypass _scratch_mount to run erofsfuse in the foreground (-f)
> +# This lets us capture libfuse's internal stderr warnings.
> +$EROFSFUSE_PROG -f $SCRATCH_DEV $SCRATCH_MNT > $tmp/fuse_err.log 2>&1 &
If this testcase is erofsfuse-specific, we should
check FSTYP="erofsfuse" instead, otherwise this
case should be skiped.
Otherwise if this test case can test the kernel
as well, we should make the kernel tested too.
Thanks,
Gao Xiang
More information about the Linux-erofs
mailing list