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 20 #include "tmux.h" 21 22 #define FUZZER_MAXLEN 512 23 #define PANE_WIDTH 80 24 #define PANE_HEIGHT 25 25 26 struct event_base *libevent; 27 28 int 29 LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) 30 { 31 struct bufferevent *vpty[2]; 32 struct window *w; 33 struct window_pane *wp; 34 int error; 35 36 /* 37 * Since AFL doesn't support -max_len paramenter we have to 38 * discard long inputs manually. 39 */ 40 if (size > FUZZER_MAXLEN) 41 return 0; 42 43 w = window_create(PANE_WIDTH, PANE_HEIGHT, 0, 0); 44 wp = window_add_pane(w, NULL, 0, 0); 45 bufferevent_pair_new(libevent, BEV_OPT_CLOSE_ON_FREE, vpty); 46 wp->ictx = input_init(wp, vpty[0]); 47 window_add_ref(w, __func__); 48 49 input_parse_buffer(wp, (u_char*) data, size); 50 while (cmdq_next(NULL) != 0) 51 ; 52 error = event_base_loop(libevent, EVLOOP_NONBLOCK); 53 if (error == -1) 54 errx(1, "event_base_loop failed"); 55 56 assert(w->references == 1); 57 window_remove_ref(w, __func__); 58 59 bufferevent_free(vpty[0]); 60 bufferevent_free(vpty[1]); 61 62 return 0; 63 } 64 65 int 66 LLVMFuzzerInitialize(__unused int *argc, __unused char ***argv) 67 { 68 const struct options_table_entry *oe; 69 70 global_environ = environ_create(); 71 global_options = options_create(NULL); 72 global_s_options = options_create(NULL); 73 global_w_options = options_create(NULL); 74 for (oe = options_table; oe->name != NULL; oe++) { 75 if (oe->scope & OPTIONS_TABLE_SERVER) 76 options_default(global_options, oe); 77 if (oe->scope & OPTIONS_TABLE_SESSION) 78 options_default(global_s_options, oe); 79 if (oe->scope & OPTIONS_TABLE_WINDOW) 80 options_default(global_w_options, oe); 81 } 82 libevent = osdep_event_init(); 83 84 options_set_number(global_w_options, "monitor-bell", 0); 85 options_set_number(global_w_options, "allow-rename", 1); 86 options_set_number(global_options, "set-clipboard", 2); 87 88 return 0; 89 } 90