| #if !defined(_GNU_SOURCE) |
| #define _GNU_SOURCE |
| #endif |
| |
| #include <ctype.h> |
| #include <error.h> |
| #include <fcntl.h> |
| #include <stdbool.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <sys/uio.h> |
| #include <unistd.h> |
| |
| #include <libhfuzz/libhfuzz.h> |
| |
| #define ARRAYSIZE(x) (sizeof(x) / sizeof(*x)) |
| |
| static int fd_tty_write; |
| static int fd_tty_read; |
| static int fd_log; |
| |
| int LLVMFuzzerInitialize(int* argc, char*** argv) |
| { |
| fd_tty_write = open("/dev/tty", O_RDWR | O_DSYNC); |
| if (fd_tty_write == -1) { |
| perror("open('/dev/tty'), O_RDWR | O_DSYNC"); |
| exit(EXIT_FAILURE); |
| } |
| fd_tty_read = open("/dev/tty", O_RDWR | O_NONBLOCK); |
| if (fd_tty_read == -1) { |
| perror("open('/dev/tty'), O_RDWR | O_NONBLOCK"); |
| exit(EXIT_FAILURE); |
| } |
| fd_log = open("./term.log", O_WRONLY | O_CREAT | O_APPEND, 0644); |
| if (fd_log == -1) { |
| perror("open('./term.log')"); |
| exit(EXIT_FAILURE); |
| } |
| return 0; |
| } |
| |
| static bool isInteresting(const char* s, size_t len) |
| { |
| for (size_t i = 0; i < len; i++) { |
| if (s[i] == '[') { |
| continue; |
| } |
| if (s[i] == ']') { |
| continue; |
| } |
| if (s[i] == '?') { |
| continue; |
| } |
| if (s[i] == ';') { |
| continue; |
| } |
| if (s[i] == 'c') { |
| continue; |
| } |
| if (s[i] == 'R') { |
| continue; |
| } |
| if (s[i] == '\0') { |
| continue; |
| } |
| if (s[i] == '\x1b') { |
| continue; |
| } |
| if (isdigit(s[i])) { |
| continue; |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| int LLVMFuzzerTestOneInput(const uint8_t* buf, size_t len) |
| { |
| write(fd_tty_write, buf, len); |
| |
| for (;;) { |
| char read_buf[1024 * 1024]; |
| ssize_t sz = read(fd_tty_read, read_buf, sizeof(read_buf)); |
| if (sz <= 0) { |
| break; |
| } |
| |
| static const char msg_in[] = "\n============ IN ============\n"; |
| static const char msg_out[] = "\n============ OUT ===========\n"; |
| static const char msg_end[] = "\n============================\n"; |
| |
| struct iovec iov[] = { |
| { |
| .iov_base = (void*)msg_in, |
| .iov_len = sizeof(msg_in), |
| }, |
| { |
| .iov_base = (void*)buf, |
| .iov_len = len, |
| }, |
| { |
| .iov_base = (void*)msg_out, |
| .iov_len = sizeof(msg_out), |
| }, |
| { |
| .iov_base = (void*)read_buf, |
| .iov_len = sz, |
| }, |
| { |
| .iov_base = (void*)msg_end, |
| .iov_len = sizeof(msg_end), |
| }, |
| }; |
| |
| writev(fd_log, iov, ARRAYSIZE(iov)); |
| } |
| |
| return 0; |
| } |