diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e134172..57c6c00d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) # TODO: Modify this when the version is released SET(BUILD_VERSION "4.5.2") +option(FUZZER "Build oss-fuzz fuzzing" OFF) + # Find Git Version Patch IF(EXISTS "${CMAKE_SOURCE_DIR}/.git") if(NOT GIT) @@ -118,3 +120,12 @@ install(DIRECTORY DESTINATION share/examples/turnserver PATTERN "rfc5769.sh" EXCLUDE ) + +if(FUZZER) + if (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "clang is require for libFuzzer") + endif() + + add_subdirectory(fuzzing) + +endif() diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt new file mode 100644 index 00000000..5824bc79 --- /dev/null +++ b/fuzzing/CMakeLists.txt @@ -0,0 +1,17 @@ +add_executable(FuzzStun FuzzStun.c) +target_link_libraries(FuzzStun turnclient ${LIB_FUZZING_ENGINE}) + +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/input/FuzzStun_seed_corpus.zip + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + + +set(FuzzStunClientSRC + ${CMAKE_CURRENT_SOURCE_DIR}/FuzzStunClient.c + ${PROJECT_SOURCE_DIR}/src/apps/common/stun_buffer.c +) + +add_executable(FuzzStunClient ${FuzzStunClientSRC}) +target_link_libraries(FuzzStunClient turnclient ${LIB_FUZZING_ENGINE}) + +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/input/FuzzStunClient_seed_corpus.zip + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/fuzzing/FuzzStun.c b/fuzzing/FuzzStun.c new file mode 100644 index 00000000..37247e29 --- /dev/null +++ b/fuzzing/FuzzStun.c @@ -0,0 +1,28 @@ +#include +#include +#include + +#include "ns_turn_utils.h" +#include "apputils.h" +#include "stun_buffer.h" + +static SHATYPE shatype = SHATYPE_SHA1; + +#define kMinInputLength 10 +#define kMaxInputLength 5120 + +extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {//rfc5769check + + if (Size < kMinInputLength || Size > kMaxInputLength){ + return 1; + } + + stun_is_command_message_full_check_str((uint8_t *)Data, Size, 1, NULL); + + uint8_t uname[33]; + uint8_t realm[33]; + uint8_t upwd[33]; + strcpy((char*) upwd, "VOkJxbRl1RmTxUk/WvJxBt"); + stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM,(uint8_t *)Data, Size, uname, realm, upwd, shatype); + return 0; +} diff --git a/fuzzing/FuzzStunClient.c b/fuzzing/FuzzStunClient.c new file mode 100644 index 00000000..88fefba0 --- /dev/null +++ b/fuzzing/FuzzStunClient.c @@ -0,0 +1,34 @@ +#include +#include +#include + +#include "ns_turn_utils.h" +#include "apputils.h" +#include "stun_buffer.h" + +#define kMinInputLength 10 +#define kMaxInputLength 5120 + +extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {//stunclient.c + + if (Size < kMinInputLength || Size > kMaxInputLength){ + return 1; + } + + stun_buffer buf; + + buf.len = Size; + memcpy(buf.buf,Data,buf.len); + + if(stun_is_command_message(&buf)){ + if(stun_is_response(&buf)){ + if(stun_is_success_response(&buf)){ + if(stun_is_binding_response(&buf)){ + return 0; + } + } + } + } + + return 1; +} diff --git a/fuzzing/build.sh b/fuzzing/build.sh new file mode 100644 index 00000000..54f53666 --- /dev/null +++ b/fuzzing/build.sh @@ -0,0 +1,51 @@ +#!/bin/bash -eu + +build(){ + export CFLAGS="$1" + export CXXFLAGS="$1" + export LIB_FUZZING_ENGINE=-fsanitize=fuzzer + + mkdir build && cd build/ + cmake -DFUZZER=ON -DLIB_FUZZING_ENGINE="$LIB_FUZZING_ENGINE" ../../. + make -j$(nproc) + + cd fuzzing/ + unzip FuzzStun_seed_corpus.zip + unzip FuzzStunClient_seed_corpus.zip + + mkdir FuzzStun_Corpus + mkdir FuzzStunClient_Corpus +} + +run(){ + DIR=build/fuzzing + if [ $1 == '0' ] + then + ./$DIR/FuzzStun $DIR/FuzzStun_Corpus/ $DIR/FuzzStun_seed_corpus + else + ./$DIR/FuzzStunClient $DIR/FuzzStunClient_Corpus/ $DIR/FuzzStunClient_seed_corpus + fi +} + +help(){ + echo "use: ./$0 ASan | UBSan | MSan | Run 0 | Run 1" +} + +if [ -z "$1" ] +then + help +elif [ $1 == "ASan" ] +then + build "-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link" +elif [ "$1" == "UBSan" ] +then + build "-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=array-bounds,bool,builtin,enum,float-divide-by-zero,function,integer-divide-by-zero,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,unsigned-integer-overflow,unreachable,vla-bound,vptr -fno-sanitize-recover=array-bounds,bool,builtin,enum,float-divide-by-zero,function,integer-divide-by-zero,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,unreachable,vla-bound,vptr -fsanitize=fuzzer-no-link" +elif [ "$1" == "MSan" ] +then + build "-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory -fsanitize-memory-track-origins -fsanitize=fuzzer-no-link" +elif [ "$1" == "Run" ] +then + run $2 +else + help +fi diff --git a/fuzzing/input/FuzzStunClient_seed_corpus.zip b/fuzzing/input/FuzzStunClient_seed_corpus.zip new file mode 100644 index 00000000..1d62c17c Binary files /dev/null and b/fuzzing/input/FuzzStunClient_seed_corpus.zip differ diff --git a/fuzzing/input/FuzzStun_seed_corpus.zip b/fuzzing/input/FuzzStun_seed_corpus.zip new file mode 100644 index 00000000..69726cff Binary files /dev/null and b/fuzzing/input/FuzzStun_seed_corpus.zip differ