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 fd_tty_write = open("/dev/tty", O_RDWR | O_DSYNC);
26 if (fd_tty_write == -1) {
27 perror("open('/dev/tty'), O_RDWR | O_DSYNC");
28 exit(EXIT_FAILURE);
29 }
30 fd_tty_read = open("/dev/tty", O_RDWR | O_NONBLOCK);
31 if (fd_tty_read == -1) {
32 perror("open('/dev/tty'), O_RDWR | O_NONBLOCK");
33 exit(EXIT_FAILURE);
34 }
35 fd_log = open("./term.log", O_WRONLY | O_CREAT | O_APPEND, 0644);
36 if (fd_log == -1) {
37 perror("open('./term.log')");
38 exit(EXIT_FAILURE);
39 }
40 return 0;
41 }
42
isInteresting(const char * s,size_t len)43 static bool isInteresting(const char* s, size_t len) {
44 for (size_t i = 0; i < len; i++) {
45 if (s[i] == '[') {
46 continue;
47 }
48 if (s[i] == ']') {
49 continue;
50 }
51 if (s[i] == '?') {
52 continue;
53 }
54 if (s[i] == ';') {
55 continue;
56 }
57 if (s[i] == 'c') {
58 continue;
59 }
60 if (s[i] == 'R') {
61 continue;
62 }
63 if (s[i] == '\0') {
64 continue;
65 }
66 if (s[i] == '\x1b') {
67 continue;
68 }
69 if (isdigit(s[i])) {
70 continue;
71 }
72 return true;
73 }
74 return false;
75 }
76
LLVMFuzzerTestOneInput(const uint8_t * buf,size_t len)77 int LLVMFuzzerTestOneInput(const uint8_t* buf, size_t len) {
78 write(fd_tty_write, buf, len);
79
80 for (;;) {
81 char read_buf[1024 * 1024];
82 ssize_t sz = read(fd_tty_read, read_buf, sizeof(read_buf));
83 if (sz <= 0) {
84 break;
85 }
86
87 static const char msg_in[] = "\n============ IN ============\n";
88 static const char msg_out[] = "\n============ OUT ===========\n";
89 static const char msg_end[] = "\n============================\n";
90
91 struct iovec iov[] = {
92 {
93 .iov_base = (void*)msg_in,
94 .iov_len = sizeof(msg_in),
95 },
96 {
97 .iov_base = (void*)buf,
98 .iov_len = len,
99 },
100 {
101 .iov_base = (void*)msg_out,
102 .iov_len = sizeof(msg_out),
103 },
104 {
105 .iov_base = (void*)read_buf,
106 .iov_len = sz,
107 },
108 {
109 .iov_base = (void*)msg_end,
110 .iov_len = sizeof(msg_end),
111 },
112 };
113
114 writev(fd_log, iov, ARRAYSIZE(iov));
115 }
116
117 return 0;
118 }
119