[PATCH v2] xfs/554: xfs add illegal bestfree array size inject for leaf dir

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Test leaf dir allocting new block when bestfree array size
less than data blocks count, which may lead to UAF.

Signed-off-by: Guo Xuenan <guoxuenan@xxxxxxxxxx>
---
 tests/xfs/554     | 96 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/554.out |  7 ++++
 2 files changed, 103 insertions(+)
 create mode 100755 tests/xfs/554
 create mode 100644 tests/xfs/554.out

diff --git a/tests/xfs/554 b/tests/xfs/554
new file mode 100755
index 00000000..dba6aefa
--- /dev/null
+++ b/tests/xfs/554
@@ -0,0 +1,96 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022 Huawei Limited.  All Rights Reserved.
+#
+# FS QA Test No. 554
+#
+# Check the running state of the XFS under illegal bestfree count
+# for leaf directory format.
+
+. ./common/preamble
+_begin_fstest auto quick
+
+# Import common functions.
+. ./common/populate
+
+# real QA test starts here
+_supported_fs xfs
+_require_scratch
+
+# Get last dirblock entries
+__lastdb_entry_list()
+{
+	local dir_ino=$1
+	local entry_list=$2
+	local nblocks=`_scratch_xfs_db -c "inode $dir_ino" -c "p core.nblocks" |
+			sed -e 's/^.*core.nblocks = //g' -e 's/\([0-9]*\).*$/\1/g'`
+	local last_db=$((nblocks / 2))
+	_scratch_xfs_db -c "inode $dir_ino" -c "dblock ${last_db}" -c 'p du' |\
+		grep ".name =" | sed -e 's/^.*.name = //g' \
+		-e 's/\"//g' > ${entry_list} ||\
+		_fail "get last dir block entries failed"
+}
+
+echo "Format and mount"
+_scratch_mkfs > $seqres.full 2>&1
+_scratch_mount
+
+echo "Create and check leaf dir"
+blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")"
+dirblksz=`$XFS_INFO_PROG "${SCRATCH_DEV}" | grep naming.*bsize |
+	sed -e 's/^.*bsize=//g' -e 's/\([0-9]*\).*$/\1/g'`
+# Usually, following routine will create a directory with one leaf block
+# and three data block, meanwhile, the last data block is not full.
+__populate_create_dir "${SCRATCH_MNT}/S_IFDIR.FMT_LEAF" "$((dirblksz / 12))"
+leaf_dir="$(__populate_find_inode "${SCRATCH_MNT}/S_IFDIR.FMT_LEAF")"
+_scratch_unmount
+
+# Delete directory entries in the last directory block,
+last_db_entries=$tmp.ldb_ents
+__lastdb_entry_list ${leaf_dir} ${last_db_entries}
+_scratch_mount
+cat ${last_db_entries} >> $seqres.full
+cat ${last_db_entries} | while read f
+do
+	rm -rf ${SCRATCH_MNT}/S_IFDIR.FMT_LEAF/$f
+done
+_scratch_unmount
+
+# Check leaf directory
+leaf_lblk="$((32 * 1073741824 / blksz))"
+node_lblk="$((64 * 1073741824 / blksz))"
+__populate_check_xfs_dir "${leaf_dir}" "leaf"
+
+# Inject abnormal bestfree count
+echo "Inject bad bestfree count."
+_scratch_xfs_db -x -c "inode ${leaf_dir}" -c "dblock ${leaf_lblk}" \
+	-c "write ltail.bestcount 0"
+# Adding new entries to S_IFDIR.FMT_LEAF. Since we delete the files
+# in last direcotry block, current dir block have no spare space for new
+# entry. With ltail.bestcount setting illegally (eg. bestcount=0), then
+# creating new directories, which will trigger xfs to allocate new dir
+# block, meanwhile, exception will be triggered.
+# Root cause is that xfs don't examin the number bestfree slots, when the
+# slots number less than dir data blocks, if we need to allocate new dir
+# data block and update the bestfree array, we will use the dir block number
+# as index to assign bestfree array, while we did not check the leaf buf
+# boundary which may cause UAF or other memory access problem.
+echo "Add directory entries to trigger exception."
+_scratch_mount
+seq 1 $((dirblksz / 24)) | while read d
+do
+mkdir "${SCRATCH_MNT}/S_IFDIR.FMT_LEAF/TEST$(printf "%.04d" "$d")" >> $seqres.full 2>&1
+done
+_scratch_unmount
+
+# Bad bestfree count should be found and fixed by xfs_repair
+_scratch_xfs_repair -n >> $seqres.full 2>&1
+egrep -q 'leaf block.*bad tail' $seqres.full && echo "Repair found problems."
+_repair_scratch_fs >> $seqres.full 2>&1 || _fail "Repair failed!"
+
+# Check demsg error
+_check_dmesg
+
+# Success, all done
+status=0
+exit
diff --git a/tests/xfs/554.out b/tests/xfs/554.out
new file mode 100644
index 00000000..d966ab0a
--- /dev/null
+++ b/tests/xfs/554.out
@@ -0,0 +1,7 @@
+QA output created by 554
+Format and mount
+Create and check leaf dir
+Inject bad bestfree count.
+ltail.bestcount = 0
+Add a directory entry to trigger exception.
+Repair found problems.
-- 
2.25.1




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux