• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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