[PATCH 3/5] fuzzy: test fuzzing realtime free space metadata

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



From: Darrick J. Wong <djwong@xxxxxxxxxx>

Fuzz the contents of the realtime bitmap and summary files to see what
happens.

Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx>
---
 common/fuzzy       |  107 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 tests/xfs/1562     |   41 ++++++++++++++++++++
 tests/xfs/1562.out |    4 ++
 tests/xfs/1563     |   41 ++++++++++++++++++++
 tests/xfs/1563.out |    4 ++
 tests/xfs/1564     |   41 ++++++++++++++++++++
 tests/xfs/1564.out |    4 ++
 tests/xfs/1565     |   41 ++++++++++++++++++++
 tests/xfs/1565.out |    4 ++
 tests/xfs/1566     |   42 ++++++++++++++++++++
 tests/xfs/1566.out |    4 ++
 tests/xfs/1567     |   42 ++++++++++++++++++++
 tests/xfs/1567.out |    4 ++
 tests/xfs/1568     |   41 ++++++++++++++++++++
 tests/xfs/1568.out |    4 ++
 tests/xfs/1569     |   41 ++++++++++++++++++++
 tests/xfs/1569.out |    4 ++
 17 files changed, 465 insertions(+), 4 deletions(-)
 create mode 100755 tests/xfs/1562
 create mode 100644 tests/xfs/1562.out
 create mode 100755 tests/xfs/1563
 create mode 100644 tests/xfs/1563.out
 create mode 100755 tests/xfs/1564
 create mode 100644 tests/xfs/1564.out
 create mode 100755 tests/xfs/1565
 create mode 100644 tests/xfs/1565.out
 create mode 100755 tests/xfs/1566
 create mode 100644 tests/xfs/1566.out
 create mode 100755 tests/xfs/1567
 create mode 100644 tests/xfs/1567.out
 create mode 100755 tests/xfs/1568
 create mode 100644 tests/xfs/1568.out
 create mode 100755 tests/xfs/1569
 create mode 100644 tests/xfs/1569.out


diff --git a/common/fuzzy b/common/fuzzy
index d8eb7d8b72..ef54f2fe2c 100644
--- a/common/fuzzy
+++ b/common/fuzzy
@@ -154,6 +154,12 @@ _scratch_xfs_dump_metadata() {
 	_scratch_xfs_db "${cmds[@]}" -c print
 }
 
+# Decide from the output of the xfs_db "stack" command if the debugger's io
+# cursor is pointed at a block that is an unstructured data format (blob).
+__scratch_xfs_detect_blob_from_stack() {
+	grep -q -E 'inode.*, type (data|rtsummary|rtbitmap)'
+}
+
 # Navigate to some part of the filesystem and print the field info.
 # The first argument is an grep filter for the fields
 # The rest of the arguments are xfs_db commands to locate the metadata.
@@ -169,7 +175,17 @@ _scratch_xfs_list_metadata_fields() {
 	for arg in "$@"; do
 		cmds+=("-c" "${arg}")
 	done
-	_scratch_xfs_db "${cmds[@]}" -c print | __filter_xfs_db_print_fields "${filter}"
+
+	# Does the path argument point towards something that is an
+	# unstructured blob?
+	if _scratch_xfs_db "${cmds[@]}" -c stack 2>/dev/null | \
+			__scratch_xfs_detect_blob_from_stack; then
+		echo "<blob>"
+		return
+	fi
+
+	_scratch_xfs_db "${cmds[@]}" -c print | \
+		__filter_xfs_db_print_fields "${filter}"
 }
 
 # Fuzz a metadata field
@@ -207,6 +223,70 @@ _scratch_xfs_fuzz_metadata_field() {
 	return 0
 }
 
+# List the fuzzing verbs available for unstructured blobs
+__scratch_xfs_list_blob_fuzz_verbs() {
+		cat << ENDL
+zeroes
+ones
+firstbit
+middlebit
+lastbit
+random
+ENDL
+}
+
+# Fuzz a metadata blob
+# The first arg is a blob fuzzing verb
+# The rest of the arguments are xfs_db commands to find the metadata.
+_scratch_xfs_fuzz_metadata_blob() {
+	local fuzzverb="$1"
+	shift
+	local trashcmd=(blocktrash -z)
+
+	local cmds=()
+	for arg in "$@"; do
+		cmds+=("-c" "${arg}")
+	done
+
+	local bytecount=$(_scratch_xfs_db "${cmds[@]}" -c "stack" | grep 'byte.*length' | awk '{print $5}')
+	local bitmax=$((bytecount * 8))
+
+	case "${fuzzverb}" in
+	"zeroes")
+		trashcmd+=(-0 -o 0 -x "${bitmax}" -y "${bitmax}");;
+	"ones")
+		trashcmd+=(-1 -o 0 -x "${bitmax}" -y "${bitmax}");;
+	"firstbit")
+		trashcmd+=(-2 -o 0 -x 1 -y 1);;
+	"middlebit")
+		trashcmd+=(-2 -o $((bitmax / 2)) -x 1 -y 1);;
+	"lastbit")
+		trashcmd+=(-2 -o "${bitmax}" -x 1 -y 1);;
+	"random")
+		trashcmd+=(-3 -o 0 -x "${bitmax}" -y "${bitmax}");;
+	*)
+		echo "Unknown blob fuzz verb \"${fuzzverb}\"."
+		return 1
+		;;
+	esac
+
+	trashcmd="${trashcmd[@]}"
+	oldval="$(_scratch_xfs_get_metadata_field "" "$@")"
+	while true; do
+		_scratch_xfs_db -x "${cmds[@]}" -c "${trashcmd}"
+		echo
+		newval="$(_scratch_xfs_get_metadata_field "" "$@" 2> /dev/null)"
+		if [ "${fuzzverb}" != "random" ] || [ "${oldval}" != "${newval}" ]; then
+			break;
+		fi
+	done
+	if [ "${oldval}" = "${newval}" ]; then
+		echo "Blob already set to new value, skipping test."
+		return 1
+	fi
+	return 0
+}
+
 # Try to forcibly unmount the scratch fs
 __scratch_xfs_fuzz_unmount()
 {
@@ -503,7 +583,11 @@ __scratch_xfs_fuzz_field_test() {
 
 	# Set the new field value
 	__fuzz_notify "+ Fuzz ${field} = ${fuzzverb}"
-	_scratch_xfs_fuzz_metadata_field "${field}" ${fuzzverb} "$@"
+	if [ "$field" = "<blob>" ]; then
+		_scratch_xfs_fuzz_metadata_blob ${fuzzverb} "$@"
+	else
+		_scratch_xfs_fuzz_metadata_field "${field}" ${fuzzverb} "$@"
+	fi
 	res=$?
 	test $res -ne 0 && return
 
@@ -587,7 +671,22 @@ _scratch_xfs_list_fuzz_verbs() {
 		echo "${SCRATCH_XFS_LIST_FUZZ_VERBS}" | tr '[ ,]' '[\n\n]'
 		return;
 	fi
-	_scratch_xfs_db -x -c 'sb 0' -c 'fuzz' | grep '^Fuzz commands:' | \
+
+	local cmds=()
+	for arg in "$@"; do
+		cmds+=("-c" "${arg}")
+	done
+	test "${#cmds[@]}" -eq 0 && cmds=('-c' 'sb 0')
+
+	# Does the path argument point towards something that is an
+	# unstructured blob?
+	if _scratch_xfs_db "${cmds[@]}" -c stack 2>/dev/null | \
+			__scratch_xfs_detect_blob_from_stack; then
+		__scratch_xfs_list_blob_fuzz_verbs
+		return
+	fi
+
+	_scratch_xfs_db -x "${cmds[@]}" -c 'fuzz' | grep '^Fuzz commands:' | \
 		sed -e 's/[,.]//g' -e 's/Fuzz commands: //g' -e 's/ /\n/g' | \
 		grep -v '^random$'
 }
@@ -605,7 +704,7 @@ _scratch_xfs_fuzz_metadata() {
 	shift; shift
 
 	fields="$(_scratch_xfs_list_metadata_fields "${filter}" "$@")"
-	verbs="$(_scratch_xfs_list_fuzz_verbs)"
+	verbs="$(_scratch_xfs_list_fuzz_verbs "$@")"
 	echo "Fields we propose to fuzz with the \"${repair}\" repair strategy: $@"
 	echo $(echo "${fields}")
 	echo "Verbs we propose to fuzz with:"
diff --git a/tests/xfs/1562 b/tests/xfs/1562
new file mode 100755
index 0000000000..015209eeb2
--- /dev/null
+++ b/tests/xfs/1562
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 1562
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+	path=('path -m /realtime/0.bitmap')
+else
+	path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'online' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1562.out b/tests/xfs/1562.out
new file mode 100644
index 0000000000..63a3bc7600
--- /dev/null
+++ b/tests/xfs/1562.out
@@ -0,0 +1,4 @@
+QA output created by 1562
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
diff --git a/tests/xfs/1563 b/tests/xfs/1563
new file mode 100755
index 0000000000..2be0870a3d
--- /dev/null
+++ b/tests/xfs/1563
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 1563
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+	path=('path -m /realtime/0.summary')
+else
+	path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'online' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1563.out b/tests/xfs/1563.out
new file mode 100644
index 0000000000..e4ca8c3733
--- /dev/null
+++ b/tests/xfs/1563.out
@@ -0,0 +1,4 @@
+QA output created by 1563
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary
diff --git a/tests/xfs/1564 b/tests/xfs/1564
new file mode 100755
index 0000000000..c0d10ff0e9
--- /dev/null
+++ b/tests/xfs/1564
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 1564
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+	path=('path -m /realtime/0.bitmap')
+else
+	path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'offline' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1564.out b/tests/xfs/1564.out
new file mode 100644
index 0000000000..afede817b8
--- /dev/null
+++ b/tests/xfs/1564.out
@@ -0,0 +1,4 @@
+QA output created by 1564
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
diff --git a/tests/xfs/1565 b/tests/xfs/1565
new file mode 100755
index 0000000000..6b4186fb3c
--- /dev/null
+++ b/tests/xfs/1565
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 1565
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+	path=('path -m /realtime/0.summary')
+else
+	path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'offline' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1565.out b/tests/xfs/1565.out
new file mode 100644
index 0000000000..7a8d9d04d6
--- /dev/null
+++ b/tests/xfs/1565.out
@@ -0,0 +1,4 @@
+QA output created by 1565
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary
diff --git a/tests/xfs/1566 b/tests/xfs/1566
new file mode 100755
index 0000000000..8d0f61ae10
--- /dev/null
+++ b/tests/xfs/1566
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 1566
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+	path=('path -m /realtime/0.bitmap')
+else
+	path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'both' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1566.out b/tests/xfs/1566.out
new file mode 100644
index 0000000000..d50e1d8539
--- /dev/null
+++ b/tests/xfs/1566.out
@@ -0,0 +1,4 @@
+QA output created by 1566
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
diff --git a/tests/xfs/1567 b/tests/xfs/1567
new file mode 100755
index 0000000000..7dc2012b67
--- /dev/null
+++ b/tests/xfs/1567
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 1567
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+	path=('path -m /realtime/0.summary')
+else
+	path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'both' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1567.out b/tests/xfs/1567.out
new file mode 100644
index 0000000000..b88fa0c1b3
--- /dev/null
+++ b/tests/xfs/1567.out
@@ -0,0 +1,4 @@
+QA output created by 1567
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary
diff --git a/tests/xfs/1568 b/tests/xfs/1568
new file mode 100755
index 0000000000..c80640ef97
--- /dev/null
+++ b/tests/xfs/1568
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 1568
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_norepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+	path=('path -m /realtime/0.bitmap')
+else
+	path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'none' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1568.out b/tests/xfs/1568.out
new file mode 100644
index 0000000000..a80f579662
--- /dev/null
+++ b/tests/xfs/1568.out
@@ -0,0 +1,4 @@
+QA output created by 1568
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
diff --git a/tests/xfs/1569 b/tests/xfs/1569
new file mode 100755
index 0000000000..e303f08ff5
--- /dev/null
+++ b/tests/xfs/1569
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 1569
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_norepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+	path=('path -m /realtime/0.summary')
+else
+	path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'none' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1569.out b/tests/xfs/1569.out
new file mode 100644
index 0000000000..d6202cc3af
--- /dev/null
+++ b/tests/xfs/1569.out
@@ -0,0 +1,4 @@
+QA output created by 1569
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary




[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux