Serenity Operating System
1/*
2 * Copyright (c) 2021, Ben Wiederhake <BenWiederhake.GitHub@gmx.de>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/DeprecatedString.h>
8#include <LibCore/ArgsParser.h>
9#include <LibCore/File.h>
10#include <LibMain/Main.h>
11#include <unistd.h>
12
13#define ENUMERATE_TARGETS(T) \
14 T(BMPLoader) \
15 T(ELF) \
16 T(Gemini) \
17 T(GIFLoader) \
18 T(HttpRequest) \
19 T(ICOLoader) \
20 T(JPEGLoader) \
21 T(Js) \
22 T(Markdown) \
23 T(PBMLoader) \
24 T(PGMLoader) \
25 T(PNGLoader) \
26 T(PPMLoader) \
27 T(QOILoader) \
28 T(TGALoader) \
29 T(RegexECMA262) \
30 T(RegexPosixExtended) \
31 T(Shell) \
32 T(TTF) \
33 T(URL)
34
35#undef __ENUMERATE_TARGET
36#define __ENUMERATE_TARGET(x) extern "C" int Test##x(uint8_t const*, size_t);
37ENUMERATE_TARGETS(__ENUMERATE_TARGET)
38#undef __ENUMERATE_TARGET
39
40#define LLVMFuzzerTestOneInput TestBMPLoader
41#include <Meta/Lagom/Fuzzers/FuzzBMPLoader.cpp>
42#undef LLVMFuzzerTestOneInput
43
44#define LLVMFuzzerTestOneInput TestELF
45#include <Meta/Lagom/Fuzzers/FuzzELF.cpp>
46#undef LLVMFuzzerTestOneInput
47
48#define LLVMFuzzerTestOneInput TestGemini
49#include <Meta/Lagom/Fuzzers/FuzzGemini.cpp>
50#undef LLVMFuzzerTestOneInput
51
52#define LLVMFuzzerTestOneInput TestGIFLoader
53#include <Meta/Lagom/Fuzzers/FuzzGIFLoader.cpp>
54#undef LLVMFuzzerTestOneInput
55
56#define LLVMFuzzerTestOneInput TestHttpRequest
57#include <Meta/Lagom/Fuzzers/FuzzHttpRequest.cpp>
58#undef LLVMFuzzerTestOneInput
59
60#define LLVMFuzzerTestOneInput TestICOLoader
61#include <Meta/Lagom/Fuzzers/FuzzICOLoader.cpp>
62#undef LLVMFuzzerTestOneInput
63
64#define LLVMFuzzerTestOneInput TestJPEGLoader
65#include <Meta/Lagom/Fuzzers/FuzzJPEGLoader.cpp>
66#undef LLVMFuzzerTestOneInput
67
68#define LLVMFuzzerTestOneInput TestJs
69#include <Meta/Lagom/Fuzzers/FuzzJs.cpp>
70#undef LLVMFuzzerTestOneInput
71
72#define LLVMFuzzerTestOneInput TestMarkdown
73#include <Meta/Lagom/Fuzzers/FuzzMarkdown.cpp>
74#undef LLVMFuzzerTestOneInput
75
76#define LLVMFuzzerTestOneInput TestPBMLoader
77#include <Meta/Lagom/Fuzzers/FuzzPBMLoader.cpp>
78#undef LLVMFuzzerTestOneInput
79
80#define LLVMFuzzerTestOneInput TestPGMLoader
81#include <Meta/Lagom/Fuzzers/FuzzPGMLoader.cpp>
82#undef LLVMFuzzerTestOneInput
83
84#define LLVMFuzzerTestOneInput TestPNGLoader
85#include <Meta/Lagom/Fuzzers/FuzzPNGLoader.cpp>
86#undef LLVMFuzzerTestOneInput
87
88#define LLVMFuzzerTestOneInput TestPPMLoader
89#include <Meta/Lagom/Fuzzers/FuzzPPMLoader.cpp>
90#undef LLVMFuzzerTestOneInput
91
92#define LLVMFuzzerTestOneInput TestQOILoader
93#include <Meta/Lagom/Fuzzers/FuzzQOILoader.cpp>
94#undef LLVMFuzzerTestOneInput
95
96#define LLVMFuzzerTestOneInput TestTGALoader
97#include <Meta/Lagom/Fuzzers/FuzzTGALoader.cpp>
98#undef LLVMFuzzerTestOneInput
99
100#define LLVMFuzzerTestOneInput TestRegexECMA262
101#include <Meta/Lagom/Fuzzers/FuzzRegexECMA262.cpp>
102#undef LLVMFuzzerTestOneInput
103
104#define LLVMFuzzerTestOneInput TestRegexPosixExtended
105#include <Meta/Lagom/Fuzzers/FuzzRegexPosixExtended.cpp>
106#undef LLVMFuzzerTestOneInput
107
108#define LLVMFuzzerTestOneInput TestShell
109#include <Meta/Lagom/Fuzzers/FuzzShell.cpp>
110#undef LLVMFuzzerTestOneInput
111
112#define LLVMFuzzerTestOneInput TestTTF
113#include <Meta/Lagom/Fuzzers/FuzzTTF.cpp>
114#undef LLVMFuzzerTestOneInput
115
116#define LLVMFuzzerTestOneInput TestURL
117#include <Meta/Lagom/Fuzzers/FuzzURL.cpp>
118#undef LLVMFuzzerTestOneInput
119
120static auto parse_target_name(StringView name)
121{
122 if (name == "list"sv) {
123 outln("The following targets are included:");
124#undef __ENUMERATE_TARGET
125#define __ENUMERATE_TARGET(x) outln(#x);
126 ENUMERATE_TARGETS(__ENUMERATE_TARGET)
127#undef __ENUMERATE_TARGET
128 exit(0);
129 }
130
131#undef __ENUMERATE_TARGET
132#define __ENUMERATE_TARGET(x) \
133 if (name == #x) \
134 return Test##x;
135 ENUMERATE_TARGETS(__ENUMERATE_TARGET)
136#undef __ENUMERATE_TARGET
137
138 warnln("Unknown fuzzing target \"{}\". Try \"list\" to get a full list.", name);
139 exit(1);
140}
141
142ErrorOr<int> serenity_main(Main::Arguments arguments)
143{
144 StringView type;
145 StringView filename;
146
147 Core::ArgsParser args_parser;
148 args_parser.add_positional_argument(type, "Type of fuzzing target to run (use \"list\" to list all existing)", "target-kind");
149 args_parser.add_positional_argument(filename, "Input file", "filename", Core::ArgsParser::Required::No);
150 args_parser.parse(arguments);
151
152 if (arguments.strings.size() <= 2 && arguments.strings[1] != "list"sv) {
153 args_parser.print_usage_terminal(stderr, arguments.strings[0]);
154 return 0;
155 }
156
157 auto fn = parse_target_name(type);
158
159 auto file = TRY(Core::File::open(filename, Core::File::OpenMode::Read));
160 auto input = TRY(file->read_until_eof());
161
162 return fn(input.data(), input.size());
163}