Lagom: Add fuzz testing for LibJS using libFuzzer ()

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
This commit is contained in:
Paul Redmond 2020-04-08 04:40:02 -04:00 committed by GitHub
parent e91cb83a23
commit 7291d5c86f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
Notes: sideshowbarker 2024-07-19 07:49:04 +09:00
4 changed files with 140 additions and 0 deletions

View file

@ -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()

View file

@ -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>
)

View file

@ -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;
}

View file

@ -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"