smc(fuzzer): random seed generation and build parameters
This patch adds build parameters to TFTF to allow more control of the
SMC fuzzing test suite as well as randomly generating seeds for the
pseudo-random number generator used for SMC fuzzing tests.
Build Options
SMC_FUZZ_CALLS_PER_INSTANCE=n: Sets the number of SMC calls per test
instance, where n is the number of calls. If not provided, this value
defaults to 100.
SMC_FUZZ_INSTANCE_COUNT=n: Sets the number of instances to run, where n
is the number of instances. If not provided, this value defaults to 1.
SMC_FUZZ_SEEDS=i,j,k,...: If randomly generated seeds are not desired,
such as a case where a certain seed results in a fail, seeds can be
provided in the build command. The seeds can either be integers or hex
values, must be formatted as shown with a comma between each seed and
no spaces, and the number of seeds provided must match
SMC_FUZZ_INSTANCE_COUNT. If not provided, seeds are randomly generated
by the build system.
Signed-off-by: John Powell <john.powell@arm.com>
Change-Id: I2cc6f4d7a02ec4b590db335ac098c9d41df42f0c
diff --git a/Makefile b/Makefile
index 3c1cf53..95f556a 100644
--- a/Makefile
+++ b/Makefile
@@ -504,8 +504,8 @@
$(Q)mkdir -p ${BUILD_PLAT}/smcf
dtc ${SMC_FUZZ_DTS} >> ${BUILD_PLAT}/smcf/dtb
$(OC) -I binary -O elf64-littleaarch64 -B aarch64 ${BUILD_PLAT}/smcf/dtb ${BUILD_PLAT}/smcf/dtb.o \
- --redefine-sym _binary___build_fvp_debug_smcf_dtb_start=_binary___dtb_start \
- --redefine-sym _binary___build_fvp_debug_smcf_dtb_end=_binary___dtb_end
+ --redefine-sym _binary___build_$(PLAT)_$(BUILD_TYPE)_smcf_dtb_start=_binary___dtb_start \
+ --redefine-sym _binary___build_$(PLAT)_$(BUILD_TYPE)_smcf_dtb_end=_binary___dtb_end
endif
$(eval $(call MAKE_IMG,tftf))
diff --git a/smc_fuzz/src/randsmcmod.c b/smc_fuzz/src/randsmcmod.c
index 2b8d017..bbd5edf 100644
--- a/smc_fuzz/src/randsmcmod.c
+++ b/smc_fuzz/src/randsmcmod.c
@@ -470,9 +470,9 @@
}
/*
- * Top of SMC fuzzing module
+ * Function executes a single SMC fuzz test instance with a supplied seed.
*/
-test_result_t smc_fuzzing_top(void)
+test_result_t smc_fuzzing_instance(uint32_t seed)
{
/*
* Setting up malloc block parameters
@@ -508,9 +508,9 @@
}
/*
- * Hard coded seed, will change in the near future for better strategy
+ * Initialize pseudo random number generator with supplied seed.
*/
- srand(89758389);
+ srand(seed);
/*
* Code to traverse the bias tree and select function based on the biaes within
@@ -532,7 +532,7 @@
* another loop to continue the process of selection until an eventual leaf
* node is found.
*/
- for (unsigned int i = 0U; i < 100U; i++) {
+ for (unsigned int i = 0U; i < SMC_FUZZ_CALLS_PER_INSTANCE; i++) {
tlnode = &ndarray[cntndarray - 1];
int nd = 0;
while (nd == 0) {
@@ -568,3 +568,59 @@
return TEST_RESULT_SUCCESS;
}
+
+/*
+ * Top of SMC fuzzing module
+ */
+test_result_t smc_fuzzing_top(void)
+{
+ /* These SMC_FUZZ_x macros are supplied by the build system. */
+ test_result_t results[SMC_FUZZ_INSTANCE_COUNT];
+ uint32_t seeds[SMC_FUZZ_INSTANCE_COUNT] = {SMC_FUZZ_SEEDS};
+ test_result_t result = TEST_RESULT_SUCCESS;
+ unsigned int i;
+
+ /* Run each instance. */
+ for (i = 0U; i < SMC_FUZZ_INSTANCE_COUNT; i++) {
+ printf("Starting SMC fuzz test with seed 0x%x\n", seeds[i]);
+ results[i] = smc_fuzzing_instance(seeds[i]);
+ }
+
+ /* Report successes and failures. */
+ printf("SMC Fuzz Test Results Summary\n");
+ for (i = 0U; i < SMC_FUZZ_INSTANCE_COUNT; i++) {
+ /* Display instance number. */
+ printf(" Instance #%d\n", i);
+
+ /* Print test results. */
+ printf(" Result: ");
+ if (results[i] == TEST_RESULT_SUCCESS) {
+ printf("SUCCESS\n");
+ } else if (results[i] == TEST_RESULT_FAIL) {
+ printf("FAIL\n");
+ /* If we got a failure, update the result value. */
+ result = TEST_RESULT_FAIL;
+ } else if (results[i] == TEST_RESULT_SKIPPED) {
+ printf("SKIPPED\n");
+ }
+
+ /* Print seed used */
+ printf(" Seed: 0x%x\n", seeds[i]);
+ }
+
+ /*
+ * Print out the smc fuzzer parameters so this test can be replicated.
+ */
+ printf("SMC fuzz build parameters to recreate this test:\n");
+ printf(" SMC_FUZZ_INSTANCE_COUNT=%u\n",
+ SMC_FUZZ_INSTANCE_COUNT);
+ printf(" SMC_FUZZ_CALLS_PER_INSTANCE=%u\n",
+ SMC_FUZZ_CALLS_PER_INSTANCE);
+ printf(" SMC_FUZZ_SEEDS=0x%x", seeds[0]);
+ for (i = 1U; i < SMC_FUZZ_INSTANCE_COUNT; i++) {
+ printf(",0x%x", seeds[i]);
+ }
+ printf("\n");
+
+ return result;
+}
diff --git a/tftf/tests/tests-smcfuzzing.mk b/tftf/tests/tests-smcfuzzing.mk
index 82b6a7c..1837ee9 100644
--- a/tftf/tests/tests-smcfuzzing.mk
+++ b/tftf/tests/tests-smcfuzzing.mk
@@ -4,6 +4,37 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+# Generate random fuzzing seeds
+# If no instance count is provided, default to 1 instance
+# If no seeds are provided, generate them randomly
+# The number of seeds provided must match the instance count
+SMC_FUZZ_INSTANCE_COUNT ?= 1
+SMC_FUZZ_SEEDS ?= $(shell python -c "from random import randint; seeds = [randint(0, 4294967295) for i in range($(SMC_FUZZ_INSTANCE_COUNT))];print(\",\".join(str(x) for x in seeds));")
+SMC_FUZZ_CALLS_PER_INSTANCE ?= 100
+
+# Validate SMC fuzzer parameters
+
+# Instance count must not be zero
+ifeq ($(SMC_FUZZ_INSTANCE_COUNT),0)
+$(error SMC_FUZZ_INSTANCE_COUNT must not be zero!)
+endif
+
+# Calls per instance must not be zero
+ifeq ($(SMC_FUZZ_CALLS_PER_INSTANCE),0)
+$(error SMC_FUZZ_CALLS_PER_INSTANCE must not be zero!)
+endif
+
+# Make sure seed count and instance count match
+TEST_SEED_COUNT = $(shell python -c "print(len(\"$(SMC_FUZZ_SEEDS)\".split(\",\")))")
+ifneq ($(TEST_SEED_COUNT), $(SMC_FUZZ_INSTANCE_COUNT))
+$(error Number of seeds does not match SMC_FUZZ_INSTANCE_COUNT!)
+endif
+
+# Add definitions to TFTF_DEFINES so they can be used in the code
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_SEEDS))
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_INSTANCE_COUNT))
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_CALLS_PER_INSTANCE))
+
TESTS_SOURCES += \
$(addprefix smc_fuzz/src/, \
randsmcmod.c \