1 /*
2 * General driver to allow command-line fuzzer (i.e. afl) to
3 * exercise the libFuzzer entrypoint.
4 */
5
6 #include <sys/types.h>
7 #include <fcntl.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #ifdef WIN32
12 #include <io.h>
13 #else
14 #include <unistd.h>
15 #endif
16
17 #define kMaxAflInputSize (1 << 20)
18 static unsigned char afl_buffer[kMaxAflInputSize];
19
20 #ifdef __AFL_LOOP
21 /* If we are built with afl-clang-fast, use persistent mode */
22 #define KEEP_FUZZING(count) __AFL_LOOP(1000)
23 #else
24 /* If we are built with afl-clang, execute each input once */
25 #define KEEP_FUZZING(count) ((count) < 1)
26 #endif
27
28 /* In ares-test-fuzz.c and ares-test-fuzz-name.c: */
29 int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size);
30
ProcessFile(int fd)31 static void ProcessFile(int fd) {
32 int count = read(fd, afl_buffer, kMaxAflInputSize);
33 /*
34 * Make a copy of the data so that it's not part of a larger
35 * buffer (where buffer overflows would go unnoticed).
36 */
37 unsigned char *copied_data = (unsigned char *)malloc(count);
38 memcpy(copied_data, afl_buffer, count);
39 LLVMFuzzerTestOneInput(copied_data, count);
40 free(copied_data);
41 }
42
main(int argc,char * argv[])43 int main(int argc, char *argv[]) {
44 if (argc == 1) {
45 int count = 0;
46 while (KEEP_FUZZING(count)) {
47 ProcessFile(fileno(stdin));
48 count++;
49 }
50 } else {
51 int ii;
52 for (ii = 1; ii < argc; ++ii) {
53 int fd = open(argv[ii], O_RDONLY);
54 if (fd < 0) {
55 fprintf(stderr, "Failed to open '%s'\n", argv[ii]);
56 continue;
57 }
58 ProcessFile(fd);
59 close(fd);
60 }
61 }
62 return 0;
63 }
64