1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (c) 2022 Google, Inc.
4  * Written by Andrew Scull <ascull@google.com>
5  */
6 
7 #include <command.h>
8 #include <common.h>
9 #include <dm.h>
10 #include <fuzzing_engine.h>
11 #include <test/fuzz.h>
12 
find_fuzz_test(const char * name)13 static struct fuzz_test *find_fuzz_test(const char *name)
14 {
15 	struct fuzz_test *fuzzer = FUZZ_TEST_START();
16 	size_t count = FUZZ_TEST_COUNT();
17 	size_t i;
18 
19 	for (i = 0; i < count; ++i) {
20 		if (strcmp(name, fuzzer->name) == 0)
21 			return fuzzer;
22 		++fuzzer;
23 	}
24 
25 	return NULL;
26 }
27 
find_fuzzing_engine(void)28 static struct udevice *find_fuzzing_engine(void)
29 {
30 	struct udevice *dev;
31 
32 	if (uclass_first_device_err(UCLASS_FUZZING_ENGINE, &dev))
33 		return NULL;
34 
35 	return dev;
36 }
37 
do_fuzz(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])38 static int do_fuzz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
39 {
40 	struct fuzz_test *fuzzer;
41 	struct udevice *dev;
42 
43 	if (argc != 2)
44 		return CMD_RET_USAGE;
45 
46 	fuzzer = find_fuzz_test(argv[1]);
47 	if (!fuzzer) {
48 		printf("Could not find fuzzer: %s\n", argv[1]);
49 		return 1;
50 	}
51 
52 	dev = find_fuzzing_engine();
53 	if (!dev) {
54 		puts("No fuzzing engine available\n");
55 		return 1;
56 	}
57 
58 	while (1) {
59 		const uint8_t *data;
60 		size_t size;
61 
62 		if (dm_fuzzing_engine_get_input(dev, &data, &size)) {
63 			puts("Fuzzing engine failed\n");
64 			return 1;
65 		}
66 
67 		fuzzer->func(data, size);
68 	}
69 
70 	return 1;
71 }
72 
73 #ifdef CONFIG_SYS_LONGHELP
74 static char fuzz_help_text[] =
75 	"[fuzz-test-name] - execute the named fuzz test\n"
76 	;
77 #endif /* CONFIG_SYS_LONGHELP */
78 
79 U_BOOT_CMD(
80 	fuzz, CONFIG_SYS_MAXARGS, 1, do_fuzz,
81 	"fuzz tests", fuzz_help_text
82 );
83