xref: /netbsd-src/external/bsd/tmux/dist/fuzz/input-fuzzer.c (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
19fb66d81Schristos /*
29fb66d81Schristos  * Copyright (c) 2020 Sergey Nizovtsev <snizovtsev@gmail.com>
39fb66d81Schristos  *
49fb66d81Schristos  * Permission to use, copy, modify, and distribute this software for any
59fb66d81Schristos  * purpose with or without fee is hereby granted, provided that the above
69fb66d81Schristos  * copyright notice and this permission notice appear in all copies.
79fb66d81Schristos  *
89fb66d81Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
99fb66d81Schristos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
109fb66d81Schristos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
119fb66d81Schristos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
129fb66d81Schristos  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
139fb66d81Schristos  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
149fb66d81Schristos  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
159fb66d81Schristos  */
169fb66d81Schristos 
179fb66d81Schristos #include <stddef.h>
189fb66d81Schristos #include <assert.h>
196db26757Swiz #include <fcntl.h>
209fb66d81Schristos 
219fb66d81Schristos #include "tmux.h"
229fb66d81Schristos 
239fb66d81Schristos #define FUZZER_MAXLEN 512
249fb66d81Schristos #define PANE_WIDTH 80
259fb66d81Schristos #define PANE_HEIGHT 25
269fb66d81Schristos 
279fb66d81Schristos struct event_base *libevent;
289fb66d81Schristos 
299fb66d81Schristos int
306db26757Swiz LLVMFuzzerTestOneInput(const u_char *data, size_t size)
319fb66d81Schristos {
329fb66d81Schristos 	struct bufferevent	*vpty[2];
339fb66d81Schristos 	struct window		*w;
349fb66d81Schristos 	struct window_pane 	*wp;
359fb66d81Schristos 	int			 error;
369fb66d81Schristos 
379fb66d81Schristos 	/*
38*f8cf1a91Swiz 	 * Since AFL doesn't support -max_len parameter we have to
399fb66d81Schristos 	 * discard long inputs manually.
409fb66d81Schristos 	 */
419fb66d81Schristos 	if (size > FUZZER_MAXLEN)
429fb66d81Schristos 		return 0;
439fb66d81Schristos 
449fb66d81Schristos 	w = window_create(PANE_WIDTH, PANE_HEIGHT, 0, 0);
459fb66d81Schristos 	wp = window_add_pane(w, NULL, 0, 0);
469fb66d81Schristos 	bufferevent_pair_new(libevent, BEV_OPT_CLOSE_ON_FREE, vpty);
476db26757Swiz 	wp->ictx = input_init(wp, vpty[0], NULL);
489fb66d81Schristos 	window_add_ref(w, __func__);
499fb66d81Schristos 
506db26757Swiz 	wp->fd = open("/dev/null", O_WRONLY);
516db26757Swiz 	if (wp->fd == -1)
526db26757Swiz 		errx(1, "open(\"/dev/null\") failed");
536db26757Swiz 	wp->event = bufferevent_new(wp->fd, NULL, NULL, NULL, NULL);
546db26757Swiz 
559fb66d81Schristos 	input_parse_buffer(wp, (u_char *)data, size);
569fb66d81Schristos 	while (cmdq_next(NULL) != 0)
579fb66d81Schristos 		;
589fb66d81Schristos 	error = event_base_loop(libevent, EVLOOP_NONBLOCK);
599fb66d81Schristos 	if (error == -1)
609fb66d81Schristos 		errx(1, "event_base_loop failed");
619fb66d81Schristos 
629fb66d81Schristos 	assert(w->references == 1);
639fb66d81Schristos 	window_remove_ref(w, __func__);
649fb66d81Schristos 
659fb66d81Schristos 	bufferevent_free(vpty[0]);
669fb66d81Schristos 	bufferevent_free(vpty[1]);
679fb66d81Schristos 
689fb66d81Schristos 	return 0;
699fb66d81Schristos }
709fb66d81Schristos 
719fb66d81Schristos int
729fb66d81Schristos LLVMFuzzerInitialize(__unused int *argc, __unused char ***argv)
739fb66d81Schristos {
749fb66d81Schristos 	const struct options_table_entry	*oe;
759fb66d81Schristos 
769fb66d81Schristos 	global_environ = environ_create();
779fb66d81Schristos 	global_options = options_create(NULL);
789fb66d81Schristos 	global_s_options = options_create(NULL);
799fb66d81Schristos 	global_w_options = options_create(NULL);
809fb66d81Schristos 	for (oe = options_table; oe->name != NULL; oe++) {
819fb66d81Schristos 		if (oe->scope & OPTIONS_TABLE_SERVER)
829fb66d81Schristos 			options_default(global_options, oe);
839fb66d81Schristos 		if (oe->scope & OPTIONS_TABLE_SESSION)
849fb66d81Schristos 			options_default(global_s_options, oe);
859fb66d81Schristos 		if (oe->scope & OPTIONS_TABLE_WINDOW)
869fb66d81Schristos 			options_default(global_w_options, oe);
879fb66d81Schristos 	}
889fb66d81Schristos 	libevent = osdep_event_init();
899fb66d81Schristos 
909fb66d81Schristos 	options_set_number(global_w_options, "monitor-bell", 0);
919fb66d81Schristos 	options_set_number(global_w_options, "allow-rename", 1);
929fb66d81Schristos 	options_set_number(global_options, "set-clipboard", 2);
936db26757Swiz 	socket_path = xstrdup("dummy");
949fb66d81Schristos 
959fb66d81Schristos 	return 0;
969fb66d81Schristos }
97