summaryrefslogtreecommitdiff
path: root/test/fuzz/cmd_fuzz.c
blob: e2f44f3ecb61bad8d3d6725d647435cf9b4d8488 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright (c) 2022 Google, Inc.
 * Written by Andrew Scull <ascull@google.com>
 */

#include <command.h>
#include <common.h>
#include <dm.h>
#include <fuzzing_engine.h>
#include <test/fuzz.h>

static struct fuzz_test *find_fuzz_test(const char *name)
{
	struct fuzz_test *fuzzer = FUZZ_TEST_START();
	size_t count = FUZZ_TEST_COUNT();
	size_t i;

	for (i = 0; i < count; ++i) {
		if (strcmp(name, fuzzer->name) == 0)
			return fuzzer;
		++fuzzer;
	}

	return NULL;
}

static struct udevice *find_fuzzing_engine(void)
{
	struct udevice *dev;

	if (uclass_first_device_err(UCLASS_FUZZING_ENGINE, &dev))
		return NULL;

	return dev;
}

static int do_fuzz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	struct fuzz_test *fuzzer;
	struct udevice *dev;

	if (argc != 2)
		return CMD_RET_USAGE;

	fuzzer = find_fuzz_test(argv[1]);
	if (!fuzzer) {
		printf("Could not find fuzzer: %s\n", argv[1]);
		return 1;
	}

	dev = find_fuzzing_engine();
	if (!dev) {
		puts("No fuzzing engine available\n");
		return 1;
	}

	while (1) {
		const uint8_t *data;
		size_t size;

		if (dm_fuzzing_engine_get_input(dev, &data, &size)) {
			puts("Fuzzing engine failed\n");
			return 1;
		}

		fuzzer->func(data, size);
	}

	return 1;
}

#ifdef CONFIG_SYS_LONGHELP
static char fuzz_help_text[] =
	"[fuzz-test-name] - execute the named fuzz test\n"
	;
#endif /* CONFIG_SYS_LONGHELP */

U_BOOT_CMD(
	fuzz, CONFIG_SYS_MAXARGS, 1, do_fuzz,
	"fuzz tests", fuzz_help_text
);