1 /* 2 * Copyright (c) 2020 Sergey Nizovtsev <snizovtsev@gmail.com> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 14 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <stddef.h> 18 #include <assert.h> 19 #include <fcntl.h> 20 21 #include "tmux.h" 22 23 #define FUZZER_MAXLEN 512 24 #define PANE_WIDTH 80 25 #define PANE_HEIGHT 25 26 27 struct event_base *libevent; 28 29 int 30 LLVMFuzzerTestOneInput(const u_char *data, size_t size) 31 { 32 struct bufferevent *vpty[2]; 33 struct window *w; 34 struct window_pane *wp; 35 int error; 36 37 /* 38 * Since AFL doesn't support -max_len paramenter we have to 39 * discard long inputs manually. 40 */ 41 if (size > FUZZER_MAXLEN) 42 return 0; 43 44 w = window_create(PANE_WIDTH, PANE_HEIGHT, 0, 0); 45 wp = window_add_pane(w, NULL, 0, 0); 46 bufferevent_pair_new(libevent, BEV_OPT_CLOSE_ON_FREE, vpty); 47 wp->ictx = input_init(wp, vpty[0], NULL); 48 window_add_ref(w, __func__); 49 50 wp->fd = open("/dev/null", O_WRONLY); 51 if (wp->fd == -1) 52 errx(1, "open(\"/dev/null\") failed"); 53 wp->event = bufferevent_new(wp->fd, NULL, NULL, NULL, NULL); 54 55 input_parse_buffer(wp, (u_char *)data, size); 56 while (cmdq_next(NULL) != 0) 57 ; 58 error = event_base_loop(libevent, EVLOOP_NONBLOCK); 59 if (error == -1) 60 errx(1, "event_base_loop failed"); 61 62 assert(w->references == 1); 63 window_remove_ref(w, __func__); 64 65 bufferevent_free(vpty[0]); 66 bufferevent_free(vpty[1]); 67 68 return 0; 69 } 70 71 int 72 LLVMFuzzerInitialize(__unused int *argc, __unused char ***argv) 73 { 74 const struct options_table_entry *oe; 75 76 global_environ = environ_create(); 77 global_options = options_create(NULL); 78 global_s_options = options_create(NULL); 79 global_w_options = options_create(NULL); 80 for (oe = options_table; oe->name != NULL; oe++) { 81 if (oe->scope & OPTIONS_TABLE_SERVER) 82 options_default(global_options, oe); 83 if (oe->scope & OPTIONS_TABLE_SESSION) 84 options_default(global_s_options, oe); 85 if (oe->scope & OPTIONS_TABLE_WINDOW) 86 options_default(global_w_options, oe); 87 } 88 libevent = osdep_event_init(); 89 90 options_set_number(global_w_options, "monitor-bell", 0); 91 options_set_number(global_w_options, "allow-rename", 1); 92 options_set_number(global_options, "set-clipboard", 2); 93 socket_path = xstrdup("dummy"); 94 95 return 0; 96 } 97