mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Scaffold for oss-fuzz, from Sergey Nizovtsev.
This commit is contained in:
parent
0dcb6e5eb4
commit
3eb1519bd7
2
.gitignore
vendored
2
.gitignore
vendored
@ -19,3 +19,5 @@ configure
|
|||||||
tmux.1.*
|
tmux.1.*
|
||||||
*.dSYM
|
*.dSYM
|
||||||
cmd-parse.c
|
cmd-parse.c
|
||||||
|
fuzz/*-fuzzer
|
||||||
|
.dirstamp
|
||||||
|
@ -202,6 +202,12 @@ if HAVE_UTF8PROC
|
|||||||
nodist_tmux_SOURCES += compat/utf8proc.c
|
nodist_tmux_SOURCES += compat/utf8proc.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if NEED_FUZZING
|
||||||
|
check_PROGRAMS = fuzz/input-fuzzer
|
||||||
|
fuzz_input_fuzzer_LDFLAGS = $(FUZZING_LIBS)
|
||||||
|
fuzz_input_fuzzer_LDADD = $(LDADD) $(tmux_OBJECTS)
|
||||||
|
endif
|
||||||
|
|
||||||
# Install tmux.1 in the right format.
|
# Install tmux.1 in the right format.
|
||||||
install-exec-hook:
|
install-exec-hook:
|
||||||
if test x@MANFORMAT@ = xmdoc; then \
|
if test x@MANFORMAT@ = xmdoc; then \
|
||||||
|
8
compat.h
8
compat.h
@ -52,6 +52,9 @@
|
|||||||
#ifndef __packed
|
#ifndef __packed
|
||||||
#define __packed __attribute__ ((__packed__))
|
#define __packed __attribute__ ((__packed__))
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef __weak
|
||||||
|
#define __weak __attribute__ ((__weak__))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ECHOPRT
|
#ifndef ECHOPRT
|
||||||
#define ECHOPRT 0
|
#define ECHOPRT 0
|
||||||
@ -395,6 +398,11 @@ int utf8proc_mbtowc(wchar_t *, const char *, size_t);
|
|||||||
int utf8proc_wctomb(char *, wchar_t);
|
int utf8proc_wctomb(char *, wchar_t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NEED_FUZZING
|
||||||
|
/* tmux.c */
|
||||||
|
#define main __weak main
|
||||||
|
#endif
|
||||||
|
|
||||||
/* getopt.c */
|
/* getopt.c */
|
||||||
extern int BSDopterr;
|
extern int BSDopterr;
|
||||||
extern int BSDoptind;
|
extern int BSDoptind;
|
||||||
|
47
configure.ac
47
configure.ac
@ -21,6 +21,26 @@ SAVED_CFLAGS="$CFLAGS"
|
|||||||
SAVED_CPPFLAGS="$CPPFLAGS"
|
SAVED_CPPFLAGS="$CPPFLAGS"
|
||||||
SAVED_LDFLAGS="$LDFLAGS"
|
SAVED_LDFLAGS="$LDFLAGS"
|
||||||
|
|
||||||
|
# Is this oss-fuzz build?
|
||||||
|
AC_ARG_ENABLE(
|
||||||
|
fuzzing,
|
||||||
|
AC_HELP_STRING(--enable-fuzzing, build fuzzers)
|
||||||
|
)
|
||||||
|
AC_ARG_VAR(
|
||||||
|
FUZZING_LIBS,
|
||||||
|
AC_HELP_STRING(libraries to link fuzzing targets with)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Set up convenient fuzzing defaults before initializing compiler.
|
||||||
|
if test "x$enable_fuzzing" = xyes; then
|
||||||
|
AC_DEFINE(NEED_FUZZING)
|
||||||
|
test "x$CC" == x && CC=clang
|
||||||
|
test "x$FUZZING_LIBS" == x && \
|
||||||
|
FUZZING_LIBS="-fsanitize=fuzzer"
|
||||||
|
test "x$SAVED_CFLAGS" == x && \
|
||||||
|
AM_CFLAGS="-g -fsanitize=fuzzer-no-link,address"
|
||||||
|
fi
|
||||||
|
|
||||||
# Set up the compiler in two different ways and say yes we may want to install.
|
# Set up the compiler in two different ways and say yes we may want to install.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
@ -54,8 +74,11 @@ if test "x$enable_static" = xyes; then
|
|||||||
LDFLAGS="$AM_LDFLAGS $SAVED_LDFLAGS"
|
LDFLAGS="$AM_LDFLAGS $SAVED_LDFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Do we need fuzzers?
|
||||||
|
AM_CONDITIONAL(NEED_FUZZING, test "x$enable_fuzzing" = xyes)
|
||||||
|
|
||||||
# Is this gcc?
|
# Is this gcc?
|
||||||
AM_CONDITIONAL(IS_GCC, test "x$GCC" = xyes)
|
AM_CONDITIONAL(IS_GCC, test "x$GCC" = xyes -a "x$enable_fuzzing" != xyes)
|
||||||
|
|
||||||
# Is this Sun CC?
|
# Is this Sun CC?
|
||||||
AC_EGREP_CPP(
|
AC_EGREP_CPP(
|
||||||
@ -117,8 +140,6 @@ AC_REPLACE_FUNCS([ \
|
|||||||
getline \
|
getline \
|
||||||
getprogname \
|
getprogname \
|
||||||
memmem \
|
memmem \
|
||||||
recallocarray \
|
|
||||||
reallocarray \
|
|
||||||
setenv \
|
setenv \
|
||||||
setproctitle \
|
setproctitle \
|
||||||
strcasestr \
|
strcasestr \
|
||||||
@ -130,6 +151,26 @@ AC_REPLACE_FUNCS([ \
|
|||||||
])
|
])
|
||||||
AC_FUNC_STRNLEN
|
AC_FUNC_STRNLEN
|
||||||
|
|
||||||
|
# Clang sanitizers wrap reallocarray even if it isn't available on the target
|
||||||
|
# system. When compiled it always returns NULL and crashes the program. To
|
||||||
|
# detect this we need a more complicated test.
|
||||||
|
AC_MSG_CHECKING([for working reallocarray])
|
||||||
|
AC_RUN_IFELSE([AC_LANG_PROGRAM(
|
||||||
|
[#include <stdlib.h>],
|
||||||
|
[return (reallocarray(NULL, 1, 1) == NULL);]
|
||||||
|
)],
|
||||||
|
AC_MSG_RESULT(yes),
|
||||||
|
[AC_LIBOBJ(reallocarray) AC_MSG_RESULT([no])]
|
||||||
|
)
|
||||||
|
AC_MSG_CHECKING([for working recallocarray])
|
||||||
|
AC_RUN_IFELSE([AC_LANG_PROGRAM(
|
||||||
|
[#include <stdlib.h>],
|
||||||
|
[return (recallocarray(NULL, 1, 1, 1) == NULL);]
|
||||||
|
)],
|
||||||
|
AC_MSG_RESULT(yes),
|
||||||
|
[AC_LIBOBJ(recallocarray) AC_MSG_RESULT([no])]
|
||||||
|
)
|
||||||
|
|
||||||
# Look for clock_gettime. Must come before event_init.
|
# Look for clock_gettime. Must come before event_init.
|
||||||
AC_SEARCH_LIBS(clock_gettime, rt)
|
AC_SEARCH_LIBS(clock_gettime, rt)
|
||||||
|
|
||||||
|
89
fuzz/input-fuzzer.c
Normal file
89
fuzz/input-fuzzer.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Sergey Nizovtsev <snizovtsev@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "tmux.h"
|
||||||
|
|
||||||
|
#define FUZZER_MAXLEN 512
|
||||||
|
#define PANE_WIDTH 80
|
||||||
|
#define PANE_HEIGHT 25
|
||||||
|
|
||||||
|
struct event_base *libevent;
|
||||||
|
|
||||||
|
int
|
||||||
|
LLVMFuzzerTestOneInput(const unsigned char *data, size_t size)
|
||||||
|
{
|
||||||
|
struct bufferevent *vpty[2];
|
||||||
|
struct window *w;
|
||||||
|
struct window_pane *wp;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since AFL doesn't support -max_len paramenter we have to
|
||||||
|
* discard long inputs manually.
|
||||||
|
*/
|
||||||
|
if (size > FUZZER_MAXLEN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
w = window_create(PANE_WIDTH, PANE_HEIGHT, 0, 0);
|
||||||
|
wp = window_add_pane(w, NULL, 0, 0);
|
||||||
|
bufferevent_pair_new(libevent, BEV_OPT_CLOSE_ON_FREE, vpty);
|
||||||
|
wp->ictx = input_init(wp, vpty[0]);
|
||||||
|
window_add_ref(w, __func__);
|
||||||
|
|
||||||
|
input_parse_buffer(wp, (u_char*) data, size);
|
||||||
|
while (cmdq_next(NULL) != 0)
|
||||||
|
;
|
||||||
|
error = event_base_loop(libevent, EVLOOP_NONBLOCK);
|
||||||
|
if (error == -1)
|
||||||
|
errx(1, "event_base_loop failed");
|
||||||
|
|
||||||
|
assert(w->references == 1);
|
||||||
|
window_remove_ref(w, __func__);
|
||||||
|
|
||||||
|
bufferevent_free(vpty[0]);
|
||||||
|
bufferevent_free(vpty[1]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LLVMFuzzerInitialize(__unused int *argc, __unused char ***argv)
|
||||||
|
{
|
||||||
|
const struct options_table_entry *oe;
|
||||||
|
|
||||||
|
global_environ = environ_create();
|
||||||
|
global_options = options_create(NULL);
|
||||||
|
global_s_options = options_create(NULL);
|
||||||
|
global_w_options = options_create(NULL);
|
||||||
|
for (oe = options_table; oe->name != NULL; oe++) {
|
||||||
|
if (oe->scope & OPTIONS_TABLE_SERVER)
|
||||||
|
options_default(global_options, oe);
|
||||||
|
if (oe->scope & OPTIONS_TABLE_SESSION)
|
||||||
|
options_default(global_s_options, oe);
|
||||||
|
if (oe->scope & OPTIONS_TABLE_WINDOW)
|
||||||
|
options_default(global_w_options, oe);
|
||||||
|
}
|
||||||
|
libevent = osdep_event_init();
|
||||||
|
|
||||||
|
options_set_number(global_w_options, "monitor-bell", 0);
|
||||||
|
options_set_number(global_w_options, "allow-rename", 1);
|
||||||
|
options_set_number(global_options, "set-clipboard", 2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
8
fuzz/input-fuzzer.dict
Normal file
8
fuzz/input-fuzzer.dict
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
"\x1b["
|
||||||
|
"1000"
|
||||||
|
"2004"
|
||||||
|
"1049"
|
||||||
|
"38;2"
|
||||||
|
"100;"
|
||||||
|
"tmux;"
|
||||||
|
"rgb:00/00/00"
|
2
fuzz/input-fuzzer.options
Normal file
2
fuzz/input-fuzzer.options
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[libfuzzer]
|
||||||
|
max_len = 512
|
Loading…
Reference in New Issue
Block a user