diff options
author | Paul Redmond <paul.redmond@gmail.com> | 2020-04-08 04:40:02 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-08 10:40:02 +0200 |
commit | 7291d5c86f0a8ab364aed8e5e4a99b3928d0ae91 (patch) | |
tree | 00e61e730706a322a920cc1367a21116f5efa005 /Meta/Lagom | |
parent | e91cb83a230a889d34ea52ae9afa119a44f59eb8 (diff) | |
download | serenity-7291d5c86f0a8ab364aed8e5e4a99b3928d0ae91.zip |
Lagom: Add fuzz testing for LibJS using libFuzzer (#1692)
Note: clang only (see https://llvm.org/docs/LibFuzzer.html)
- add FuzzJs which will run the LibJS parser on random javascript inputs
- added a basic dictionary of javascript tokens
To use fuzzer:
CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake -DENABLE_FUZZER_SANITIZER=1 ..
Fuzzers/FuzzJs -dict=../Fuzzers/FuzzJs.dict
Diffstat (limited to 'Meta/Lagom')
-rw-r--r-- | Meta/Lagom/CMakeLists.txt | 10 | ||||
-rw-r--r-- | Meta/Lagom/Fuzzers/CMakeLists.txt | 9 | ||||
-rw-r--r-- | Meta/Lagom/Fuzzers/FuzzJs.cpp | 14 | ||||
-rw-r--r-- | Meta/Lagom/Fuzzers/FuzzJs.dict | 107 |
4 files changed, 140 insertions, 0 deletions
diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index cc8138b68c..faabb4c52c 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -24,6 +24,12 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=undefined") endif() + option(ENABLE_FUZZER_SANITIZER "Enable fuzzer sanitizer testing in clang" FALSE) + if (ENABLE_FUZZER_SANITIZER) + add_definitions(-fsanitize=fuzzer -fno-omit-frame-pointer) + set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=fuzzer-no-link") + endif() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}") @@ -57,3 +63,7 @@ add_executable(js ../../Userland/js.cpp) target_link_libraries(js lagom) target_link_libraries(js stdc++) target_link_libraries(js pthread) + +if (ENABLE_FUZZER_SANITIZER) + add_subdirectory(Fuzzers) +endif() diff --git a/Meta/Lagom/Fuzzers/CMakeLists.txt b/Meta/Lagom/Fuzzers/CMakeLists.txt new file mode 100644 index 0000000000..7788c5078a --- /dev/null +++ b/Meta/Lagom/Fuzzers/CMakeLists.txt @@ -0,0 +1,9 @@ +add_executable(FuzzJs FuzzJs.cpp) +target_compile_options(FuzzJs + PRIVATE $<$<C_COMPILER_ID:Clang>:-g -O1 -fsanitize=fuzzer> + ) + +target_link_libraries(FuzzJs + PUBLIC lagom + PRIVATE $<$<C_COMPILER_ID:Clang>:-fsanitize=fuzzer> + ) diff --git a/Meta/Lagom/Fuzzers/FuzzJs.cpp b/Meta/Lagom/Fuzzers/FuzzJs.cpp new file mode 100644 index 0000000000..0288d4b58f --- /dev/null +++ b/Meta/Lagom/Fuzzers/FuzzJs.cpp @@ -0,0 +1,14 @@ +#include <AK/StringView.h> +#include <LibJS/Lexer.h> +#include <LibJS/Parser.h> +#include <stddef.h> +#include <stdint.h> + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + auto js = AK::StringView(static_cast<const unsigned char*>(data), size); + auto lexer = JS::Lexer(js); + auto parser = JS::Parser(lexer); + parser.parse_program(); + return 0; +} diff --git a/Meta/Lagom/Fuzzers/FuzzJs.dict b/Meta/Lagom/Fuzzers/FuzzJs.dict new file mode 100644 index 0000000000..9db37bfe4b --- /dev/null +++ b/Meta/Lagom/Fuzzers/FuzzJs.dict @@ -0,0 +1,107 @@ +# +# AFL dictionary for JavaScript +# ----------------------------- +# +# Contains basic reserved keywords and syntax building blocks. +# +# Created by Michal Zalewski <lcamtuf@google.com> +# + +keyword_arguments="arguments" +keyword_break="break" +keyword_case="case" +keyword_catch="catch" +keyword_const="const" +keyword_continue="continue" +keyword_debugger="debugger" +keyword_decodeURI="decodeURI" +keyword_default="default" +keyword_delete="delete" +keyword_do="do" +keyword_else="else" +keyword_escape="escape" +keyword_eval="eval" +keyword_export="export" +keyword_finally="finally" +keyword_for="for (a=0;a<2;a++)" +keyword_function="function" +keyword_if="if" +keyword_in="in" +keyword_instanceof="instanceof" +keyword_isNaN="isNaN" +keyword_let="let" +keyword_new="new" +keyword_parseInt="parseInt" +keyword_return="return" +keyword_switch="switch" +keyword_this="this" +keyword_throw="throw" +keyword_try="try" +keyword_typeof="typeof" +keyword_var="var" +keyword_void="void" +keyword_while="while" +keyword_with="with" + +misc_1=" 1" +misc_a="a" +misc_array=" [1]" +misc_assign=" a=1" +misc_code_block=" {1}" +misc_colon_num=" 1:" +misc_colon_string=" 'a':" +misc_comma=" ," +misc_comment_block=" /* */" +misc_comment_line=" //" +misc_cond=" 1?2:3" +misc_dec=" --" +misc_div=" /" +misc_equals=" =" +misc_fn=" a()" +misc_identical=" ===" +misc_inc=" ++" +misc_minus=" -" +misc_modulo=" %" +misc_parentheses=" ()" +misc_parentheses_1=" (1)" +misc_parentheses_1x4=" (1,1,1,1)" +misc_parentheses_a=" (a)" +misc_period="." +misc_plus=" +" +misc_plus_assign=" +=" +misc_regex=" /a/g" +misc_rol=" <<<" +misc_semicolon=" ;" +misc_serialized_object=" {'a': 1}" +misc_string=" 'a'" +misc_unicode=" '\\u0001'" + +object_Array=" Array" +object_Boolean=" Boolean" +object_Date=" Date" +object_Function=" Function" +object_Infinity=" Infinity" +object_Int8Array=" Int8Array" +object_Math=" Math" +object_NaN=" NaN" +object_Number=" Number" +object_Object=" Object" +object_RegExp=" RegExp" +object_String=" String" +object_Symbol=" Symbol" +object_false=" false" +object_null=" null" +object_true=" true" + +prop_charAt=".charAt" +prop_concat=".concat" +prop_constructor=".constructor" +prop_destructor=".destructor" +prop_length=".length" +prop_match=".match" +prop_proto=".__proto__" +prop_prototype=".prototype" +prop_slice=".slice" +prop_toCode=".toCode" +prop_toString=".toString" +prop_valueOf=".valueOf" |