1 #if !defined(_GNU_SOURCE)
2 #define _GNU_SOURCE
3 #endif
4
5 #include <ctype.h>
6 #include <error.h>
7 #include <fcntl.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <sys/uio.h>
14 #include <unistd.h>
15
16 #include <libhfuzz/libhfuzz.h>
17
18 #define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
19
20 static int fd_tty_write;
21 static int fd_tty_read;
22 static int fd_log;
23
LLVMFuzzerInitialize(int * argc,char *** argv)24 int LLVMFuzzerInitialize(int* argc, char*** argv)
25 {
26 fd_tty_write = open("/dev/tty", O_RDWR | O_DSYNC);
27 if (fd_tty_write == -1) {
28 perror("open('/dev/tty'), O_RDWR | O_DSYNC");
29 exit(EXIT_FAILURE);
30 }
31 fd_tty_read = open("/dev/tty", O_RDWR | O_NONBLOCK);
32 if (fd_tty_read == -1) {
33 perror("open('/dev/tty'), O_RDWR | O_NONBLOCK");
34 exit(EXIT_FAILURE);
35 }
36 fd_log = open("./term.log", O_WRONLY | O_CREAT | O_APPEND, 0644);
37 if (fd_log == -1) {
38 perror("open('./term.log')");
39 exit(EXIT_FAILURE);
40 }
41 return 0;
42 }
43
isInteresting(const char * s,size_t len)44 static bool isInteresting(const char* s, size_t len)
45 {
46 for (size_t i = 0; i < len; i++) {
47 if (s[i] == '[') {
48 continue;
49 }
50 if (s[i] == ']') {
51 continue;
52 }
53 if (s[i] == '?') {
54 continue;
55 }
56 if (s[i] == ';') {
57 continue;
58 }
59 if (s[i] == 'c') {
60 continue;
61 }
62 if (s[i] == 'R') {
63 continue;
64 }
65 if (s[i] == '\0') {
66 continue;
67 }
68 if (s[i] == '\x1b') {
69 continue;
70 }
71 if (isdigit(s[i])) {
72 continue;
73 }
74 return true;
75 }
76 return false;
77 }
78
LLVMFuzzerTestOneInput(const uint8_t * buf,size_t len)79 int LLVMFuzzerTestOneInput(const uint8_t* buf, size_t len)
80 {
81 write(fd_tty_write, buf, len);
82
83 for (;;) {
84 char read_buf[1024 * 1024];
85 ssize_t sz = read(fd_tty_read, read_buf, sizeof(read_buf));
86 if (sz <= 0) {
87 break;
88 }
89
90 static const char msg_in[] = "\n============ IN ============\n";
91 static const char msg_out[] = "\n============ OUT ===========\n";
92 static const char msg_end[] = "\n============================\n";
93
94 struct iovec iov[] = {
95 {
96 .iov_base = (void*)msg_in,
97 .iov_len = sizeof(msg_in),
98 },
99 {
100 .iov_base = (void*)buf,
101 .iov_len = len,
102 },
103 {
104 .iov_base = (void*)msg_out,
105 .iov_len = sizeof(msg_out),
106 },
107 {
108 .iov_base = (void*)read_buf,
109 .iov_len = sz,
110 },
111 {
112 .iov_base = (void*)msg_end,
113 .iov_len = sizeof(msg_end),
114 },
115 };
116
117 writev(fd_log, iov, ARRAYSIZE(iov));
118 }
119
120 return 0;
121 }
122