From 56bfac7e42cf616e8f5f9b8d60b95def580d95e7 Mon Sep 17 00:00:00 2001 From: Kuang-che Wu Date: Thu, 20 Oct 2016 20:13:49 +0900 Subject: [PATCH] Revise chewing fuzzer (#48) 1. Specify unique name for temp userdb. So we can run multiple fuzzers at the same time. 2. Reorganized as three fuzzers for different variants. So we can prioritize easily (default first, dynamic config last) --- libchewing/Dockerfile | 2 +- libchewing/build.sh | 12 ++++--- libchewing/chewing_default_fuzzer.c | 15 ++++++++ libchewing/chewing_dynamic_config_fuzzer.c | 15 ++++++++ libchewing/chewing_fuzzer.c | 40 ---------------------- libchewing/chewing_fuzzer_common.c | 26 ++++++++++++++ libchewing/chewing_fuzzer_common.h | 13 +++++++ libchewing/chewing_random_init_fuzzer.c | 15 ++++++++ 8 files changed, 92 insertions(+), 46 deletions(-) create mode 100644 libchewing/chewing_default_fuzzer.c create mode 100644 libchewing/chewing_dynamic_config_fuzzer.c delete mode 100644 libchewing/chewing_fuzzer.c create mode 100644 libchewing/chewing_fuzzer_common.c create mode 100644 libchewing/chewing_fuzzer_common.h create mode 100644 libchewing/chewing_random_init_fuzzer.c diff --git a/libchewing/Dockerfile b/libchewing/Dockerfile index 389edaadd..b3625028c 100644 --- a/libchewing/Dockerfile +++ b/libchewing/Dockerfile @@ -19,4 +19,4 @@ MAINTAINER kcwu@csie.org RUN apt-get install -y make autoconf automake libtool texinfo RUN git clone https://github.com/chewing/libchewing.git -COPY build.sh chewing_fuzzer.c /src/ +COPY build.sh chewing_fuzzer_common.[ch] chewing_*_fuzzer.c /src/ diff --git a/libchewing/build.sh b/libchewing/build.sh index b6fab1bc6..a4db16794 100755 --- a/libchewing/build.sh +++ b/libchewing/build.sh @@ -25,11 +25,13 @@ make clean all # build your fuzzer(s) make -C test CFLAGS="$CFLAGS -Dmain=stress_main -Drand=get_fuzz_input" stress.o -$CC $CFLAGS \ - -o /out/chewing_fuzzer \ - /src/chewing_fuzzer.c \ - test/stress.o test/.libs/libtesthelper.a src/.libs/libchewing.a \ - -lfuzzer $FUZZER_LDFLAGS +for variant in default random_init dynamic_config; do + $CC $CFLAGS \ + -o /out/chewing_${variant}_fuzzer \ + /src/chewing_${variant}_fuzzer.c /src/chewing_fuzzer_common.c \ + test/stress.o test/.libs/libtesthelper.a src/.libs/libchewing.a \ + -lfuzzer $FUZZER_LDFLAGS +done # install data files make -C data pkgdatadir=/out install diff --git a/libchewing/chewing_default_fuzzer.c b/libchewing/chewing_default_fuzzer.c new file mode 100644 index 000000000..dd6fc7a84 --- /dev/null +++ b/libchewing/chewing_default_fuzzer.c @@ -0,0 +1,15 @@ +#include + +#include "chewing_fuzzer_common.h" + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + fuzz_input = fuzz_ptr = data; + fuzz_size = size; + + const char* stress_argv[] = { + "./chewing_fuzzer", "-loop", "1", NULL, + }; + stress_main(sizeof(stress_argv) / sizeof(stress_argv[0]) - 1, + (char**)stress_argv); + return 0; +} diff --git a/libchewing/chewing_dynamic_config_fuzzer.c b/libchewing/chewing_dynamic_config_fuzzer.c new file mode 100644 index 000000000..5479c1ee1 --- /dev/null +++ b/libchewing/chewing_dynamic_config_fuzzer.c @@ -0,0 +1,15 @@ +#include + +#include "chewing_fuzzer_common.h" + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + fuzz_input = fuzz_ptr = data; + fuzz_size = size; + + const char* stress_argv[] = { + "./chewing_fuzzer", "-loop", "1", "-extra", NULL, + }; + stress_main(sizeof(stress_argv) / sizeof(stress_argv[0]) - 1, + (char**)stress_argv); + return 0; +} diff --git a/libchewing/chewing_fuzzer.c b/libchewing/chewing_fuzzer.c deleted file mode 100644 index e7b6e610d..000000000 --- a/libchewing/chewing_fuzzer.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include -#include -#include - -static const uint8_t* fuzz_ptr; -static const uint8_t* fuzz_input; -static size_t fuzz_size; - -int stress_main(int argc, char** argv); - - int LLVMFuzzerInitialize(int* argc, char*** argv) { - char* exe_path = (*argv)[0]; - char* dir = dirname(exe_path); - // Assume data files are at the same location as executable. - setenv("CHEWING_PATH", dir, 0); - setenv("CHEWING_USER_PATH", "/tmp", 0); - return 0; - } - -int get_fuzz_input() { - if (fuzz_ptr - fuzz_input >= fuzz_size) - return EOF; - return *fuzz_ptr++; -} - -int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - fuzz_input = fuzz_ptr = data; - fuzz_size = size; - - const char *stress_argv[] = { - "./chewing_fuzzer", - "-extra", - "-loop", "1", - NULL, - }; - stress_main(4, (char**)stress_argv); - return 0; -} diff --git a/libchewing/chewing_fuzzer_common.c b/libchewing/chewing_fuzzer_common.c new file mode 100644 index 000000000..de249df67 --- /dev/null +++ b/libchewing/chewing_fuzzer_common.c @@ -0,0 +1,26 @@ +#include "chewing_fuzzer_common.h" + +#include +#include +#include + +static char userphrase_path[] = "/tmp/chewing_userphrase.db.XXXXXX"; + +int LLVMFuzzerInitialize(int* argc, char*** argv) { + char* exe_path = (*argv)[0]; + char* dir = dirname(exe_path); + // Assume data files are at the same location as executable. + setenv("CHEWING_PATH", dir, 0); + + // Specify user db of this process. So we can run multiple fuzzers at the + // same time. + mktemp(userphrase_path); + setenv("TEST_USERPHRASE_PATH", userphrase_path, 0); + return 0; +} + +int get_fuzz_input() { + if (fuzz_ptr - fuzz_input >= fuzz_size) + return EOF; + return *fuzz_ptr++; +} diff --git a/libchewing/chewing_fuzzer_common.h b/libchewing/chewing_fuzzer_common.h new file mode 100644 index 000000000..5032d655c --- /dev/null +++ b/libchewing/chewing_fuzzer_common.h @@ -0,0 +1,13 @@ +#ifndef CHEWING_FUZZER_COMMON_H +#define CHEWING_FUZZER_COMMON_H + +#include +#include + +const uint8_t* fuzz_ptr; +const uint8_t* fuzz_input; +size_t fuzz_size; + +int stress_main(int argc, char** argv); + +#endif diff --git a/libchewing/chewing_random_init_fuzzer.c b/libchewing/chewing_random_init_fuzzer.c new file mode 100644 index 000000000..3e6a841b5 --- /dev/null +++ b/libchewing/chewing_random_init_fuzzer.c @@ -0,0 +1,15 @@ +#include + +#include "chewing_fuzzer_common.h" + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + fuzz_input = fuzz_ptr = data; + fuzz_size = size; + + const char* stress_argv[] = { + "./chewing_fuzzer", "-loop", "1", "-init", "-extra", NULL, + }; + stress_main(sizeof(stress_argv) / sizeof(stress_argv[0]) - 1, + (char**)stress_argv); + return 0; +}