diff options
| author | Zhihao Cheng <chengzhihao1@huawei.com> | 2024-11-11 17:08:22 +0800 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2024-11-11 10:32:46 +0100 | 
| commit | 075e40c91c1a9ae0ce415699b0278d880c098128 (patch) | |
| tree | c75e4aa0cebea4e04258168121415f09d9932788 /tests/ubifs_tools-tests | |
| parent | fcc70be5f29872c11e3c8be36c9d3b9c0d016080 (diff) | |
tests: ubifs_tools: fsck_tests: Add corrupt+fsck+fault_inject test
Inject memory/io fault while doing fsck for corrupted UBIFS images.
This testcase mainly checks whether fsck.ubifs has problems (eg.
UAF, null-ptr-def, etc.) in random error paths. Besides, it provides
a similar way to simulate powercut during fsck, and checks whether
the fsck.ubifs can fix an UBIFS image after many rounds interrupted
by kinds of errors.
Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'tests/ubifs_tools-tests')
| -rw-r--r-- | tests/ubifs_tools-tests/Makemodule.am | 3 | ||||
| -rwxr-xr-x | tests/ubifs_tools-tests/fsck_tests/cycle_corrupted_fsck_fault_inject.sh.in | 225 | ||||
| -rwxr-xr-x | tests/ubifs_tools-tests/lib/common.sh.in | 3 | 
3 files changed, 229 insertions, 2 deletions
| diff --git a/tests/ubifs_tools-tests/Makemodule.am b/tests/ubifs_tools-tests/Makemodule.am index d54514d..932a2bc 100644 --- a/tests/ubifs_tools-tests/Makemodule.am +++ b/tests/ubifs_tools-tests/Makemodule.am @@ -2,4 +2,5 @@ test_SCRIPTS += \  	tests/ubifs_tools-tests/lib/common.sh \  	tests/ubifs_tools-tests/fsck_tests/authentication_refuse.sh \  	tests/ubifs_tools-tests/fsck_tests/cycle_mount_fsck_check.sh \ -	tests/ubifs_tools-tests/fsck_tests/powercut_fsck_mount.sh +	tests/ubifs_tools-tests/fsck_tests/powercut_fsck_mount.sh \ +	tests/ubifs_tools-tests/fsck_tests/cycle_corrupted_fsck_fault_inject.sh diff --git a/tests/ubifs_tools-tests/fsck_tests/cycle_corrupted_fsck_fault_inject.sh.in b/tests/ubifs_tools-tests/fsck_tests/cycle_corrupted_fsck_fault_inject.sh.in new file mode 100755 index 0000000..2073fec --- /dev/null +++ b/tests/ubifs_tools-tests/fsck_tests/cycle_corrupted_fsck_fault_inject.sh.in @@ -0,0 +1,225 @@ +#!/bin/sh +# Copyright (c), 2024, Huawei Technologies Co, Ltd. +# Author: Zhihao Cheng <chengzhihao1@huawei.com> +# +# Test Description: +# For many kinds of flash, do following things +#  1. mount UBIFS +#  2. fsstress && unmount +#  3. inject corruption into UBIFS image randomly +#  3. fsck UBIFS && inject kinds of errors(memory, io) +#  4. check UBIFS mounting result +# Running time: 15min + +TESTBINDIR=@TESTBINDIR@ +source $TESTBINDIR/common.sh + +function run_test() +{ +	local simulator="$1"; +	local size="$2"; +	local peb_size="$3"; +	local page_size="$4"; +	local encryption=$5; + +	echo "======================================================================" +	printf "%s" "$simulator: ${size}MiB PEB size ${peb_size}KiB" +	if [ "$simulator" = "nandsim" ]; then +		printf " %s" "page size ${page_size}Bytes" +	fi +	printf " $encryption\n" + +	if [ "$simulator" = "nandsim" ]; then +		$TESTBINDIR/load_nandsim.sh "$size" "$peb_size" "$page_size" || echo "cannot load nandsim"; +		mtdnum="$(find_mtd_device "$nandsim_patt")" +	elif [ "$simulator" = "mtdram" ]; then +		load_mtdram "$size" "$peb_size" || echo "cannot load mtdram" +		mtdnum="$(find_mtd_device "$mtdram_patt")" +	else +		fatal "$simulator is not supported" +	fi + +	flash_eraseall /dev/mtd$mtdnum +	modprobe ubi mtd="$mtdnum,$page_size" || fatal "modprobe ubi fail" +	ubimkvol -N vol_test -m -n 0 /dev/ubi$UBI_NUM || fatal "mkvol fail" +	modprobe ubifs || fatal "modprobe ubifs fail" +	mount_ubifs $DEV $MNT || fatal "mount ubifs fail" +	if [[ "$encryption" == "encrypted" ]]; then +		encryption_gen_key +		encryption_set_key $MNT +	fi + +	fsstress -d $MNT -l0 -p4 -n10000 & + +	sleep $((RANDOM % 20)) + +	ps -e | grep -w fsstress > /dev/null 2>&1 +	while [ $? -eq 0 ] +	do +		killall -9 fsstress > /dev/null 2>&1 +		sleep 1 +		ps -e | grep -w fsstress > /dev/null 2>&1 +	done + +	while true +	do +		res=`mount | grep "$MNT"` +		if [[ "$res" == "" ]] +		then +			break; +		fi +		umount $MNT +		sleep 0.1 +	done + +	# inject corruption +	times=$((RANDOM % 10)) +	let times=$times+10 +	i=0 +	tot_peb=`cat /sys/class/ubi/ubi$UBI_NUM/total_eraseblocks`; + +	modprobe -r ubifs +	modprobe -r ubi # Stop wear-leveling & erasing worker +	while [[ $i -lt $times ]] +	do +		let i=$i+1; +		peb=$((RANDOM % $tot_peb)); +		pg=`expr $peb_size \* 1024`; +		peb_off=`expr $pg \* $peb` +		pages=`expr $pg / $page_size`; +		pg=`expr $pages - 2`; +		pg=$((RANDOM % $pg)); +		pg_off=`expr $pg + 2`; +		pg_start=`expr $pages \* $peb`; +		pg=`expr $pg_start + $pg_off`; +		vid_pg=`expr $pg_start + 1`; +		dd if=/dev/mtd$mtdnum of=$TMP_FILE bs=$page_size skip=$vid_pg count=1 2>/dev/null; +		content=`cat $TMP_FILE | grep UBI!`; # vid header magic +		if [[ "$content" == "" ]]; then +			# Skip free PEB, otherwise LEB data could be overwritten in UBIFS +			continue; +		fi +		if [[ $((RANDOM % 2)) == 0 ]]; then +			# Corrupts 1 page +			dd if=/dev/urandom of=/dev/mtd$mtdnum bs=$page_size seek=$pg count=1; +		else +			# Erase 1 LEB, TNC points to an unmapped area +			flash_erase /dev/mtd$mtdnum $peb_off 1 +		fi +	done +	rm -f $TMP_FILE 2>/dev/null +	sync + +	skip=0 +	modprobe ubi mtd="$mtdnum,$page_size" +	ret=$? +	if [[ $ret != 0 ]] +	then +		skip=1 +		echo "UBI layout volume is corrupted, skip" +	fi + +	if [[ $skip == 0 ]]; then +		modprobe ubifs || fatal "modprobe ubifs2 fail" +		dmesg -c > /dev/null + +		round=0 +		while [[ $round -lt 50 ]]; +		do +			let round=$round+1 +			inject_mem=0 + +			fsck.ubifs -yb $DEV 2>&1 > $LOG_FILE & +			pid=$! +			if [[ $((RANDOM % 2)) == 0 ]]; then +				inject_mem_err $pid +				inject_mem=1 +			fi +			inject_io_err +			wait $pid +			cat $LOG_FILE +			if [[ $inject_mem == 1 ]]; then +				cancel_mem_err +			fi +			cancel_io_err + +			# UBI could become ro-mode, reload it +			modprobe -r ubifs +			modprobe -r ubi +			modprobe ubi mtd="$mtdnum,$page_size" || fatal "modprobe ubi2 fail" +			modprobe ubifs || fatal "modprobe ubifs3 fail" +		done + +		fsck.ubifs -yb $DEV 2>&1 > $LOG_FILE +		res=$? +		cat $LOG_FILE +		let "ret=$res&~$FSCK_NONDESTRUCT" +		if [[ $ret != $FSCK_OK ]] +		then +			# Skip superblock error +			log=`cat $LOG_FILE | grep "bad node at LEB 0:"` +			if [[ "$log" != "" ]] +			then +				skip=1 +				echo "SB is corrupted, skip fsck & mounting" +			else +				fatal "fsck fail $res" +			fi +		fi + +		if [[ $skip == 0 ]]; then +			enable_chkfs + +			mount_ubifs $DEV $MNT "noauthentication" "noatime" +			res=$? +			if [[ $res != 0 ]] +			then +				fatal "mount fail $res" +			fi + +			if [[ "$encryption" == "encrypted" ]]; then +				# Ignore the encrypting error, root dir could be +			        # corrupted, the new root dir cannot be +			        # encrypted because it is not empty. +				encryption_set_key $MNT 1 +			fi + +			du -sh $MNT > /dev/null  # Make sure all files are accessible +			ret=$? +			if [[ $ret != 0 ]]; then +				fatal "Cannot access all files" +			fi +			# check_err_msg is not suggested in this testcase, because +			# ubi_io_read(triggered by wear_leveling_worker -> ubi_eba_copy_leb) +			# could print stack if ecc uncorrectable errors are detected. + +			umount $MNT +			res=$? +			if [[ $res != 0 ]] +			then +				fatal "unmount fail $res" +			fi +		fi + +		modprobe -r ubifs +		modprobe -r ubi +	fi +	modprobe -r $simulator + +	echo "----------------------------------------------------------------------" +} + +check_fsstress +start_t=$(date +%s) +echo "Do corrruption+cycle_fsck_fault_injection test in kinds of flashes" +for simulator in "mtdram" "nandsim"; do +	for encryption in "encrypted" "noencrypted"; do +		run_test "$simulator" "16" "16" "512" $encryption +		run_test "$simulator" "256" "128" "2048" $encryption +		run_test "$simulator" "1024" "512" "2048" $encryption +	done +done +end_t=$(date +%s) +time_cost=$(( end_t - start_t )) +echo "Success, cost $time_cost seconds" +exit 0 diff --git a/tests/ubifs_tools-tests/lib/common.sh.in b/tests/ubifs_tools-tests/lib/common.sh.in index 5a07ebc..a27fe10 100755 --- a/tests/ubifs_tools-tests/lib/common.sh.in +++ b/tests/ubifs_tools-tests/lib/common.sh.in @@ -234,12 +234,13 @@ function encryption_gen_key()  function encryption_set_key()  {  	mnt=$1 +	ignore_err=$2  	# https://github.com/google/fscryptctl  	key=$(fscryptctl add_key $mnt < $KEY_FILE)  	fscryptctl set_policy $key $mnt  	#fscryptctl get_policy $mnt  	ret=$? -	if [[ $ret != 0 ]]; then +	if [[ $ret != 0 && $ignore_err != 1 ]]; then  		fatal "set encryption policy failed"  	fi  } | 
