• 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     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