From dda0c9975932d9badee856ba1cabc6d86f7eff44 Mon Sep 17 00:00:00 2001 From: Arjun <36335769+0x34d@users.noreply.github.com> Date: Tue, 25 Oct 2022 01:31:58 +0530 Subject: [PATCH] fuzzing support (#982) Adding fuzzing to finding memory-corruption-related bugs. Hello coturn team, Can you check this pr harness suite for creating harnesses and compiling harnesses? Any other thoughts on adding a new interface for fuzzing support ? Signed-off-by: 0x34d Signed-off-by: 0x34d --- CMakeLists.txt | 11 ++++ fuzzing/CMakeLists.txt | 17 +++++++ fuzzing/FuzzStun.c | 28 ++++++++++ fuzzing/FuzzStunClient.c | 34 +++++++++++++ fuzzing/build.sh | 51 +++++++++++++++++++ fuzzing/input/FuzzStunClient_seed_corpus.zip | Bin 0 -> 1798 bytes fuzzing/input/FuzzStun_seed_corpus.zip | Bin 0 -> 1540 bytes 7 files changed, 141 insertions(+) create mode 100644 fuzzing/CMakeLists.txt create mode 100644 fuzzing/FuzzStun.c create mode 100644 fuzzing/FuzzStunClient.c create mode 100644 fuzzing/build.sh create mode 100644 fuzzing/input/FuzzStunClient_seed_corpus.zip create mode 100644 fuzzing/input/FuzzStun_seed_corpus.zip 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 0000000000000000000000000000000000000000..1d62c17c73b51d96535f89ac0c97d369d8ef5940 GIT binary patch literal 1798 zcmWIWW@Zs#0D%qjbVI=mC?UW!b96fR3K(pSl11Am~JfQL8_}hwRIp&c5 z?dfHKp~(}O`Q7KxISzC#=gn}|MM0pUOxBi2pcckw5i(9|0JcP6gX~Q?%3&gM1QM`c!%hp z=F(WvnBK2vzVe7jh%_uSl-lFHf7K*rqi|=7EpC1{uWUM<6O?dc7hCYL1{uo>?f ziPEihJoc<@=9$AMBFmFq%QjTzL&k$!eam?VAkRep$A)Rs3MDblbVB;Yxeh_5ZBkWFWqq+O(ZyZ0bp7>d*sQTg?mtKYmJFPE${v#nF$>i|N?*9VY#uA`=d7qSy=-imI!mg4>>g^}0#GwaGS_AicQZ#JdO;4RtB*Cv}_9#;L%D(nmY zlKCI^6|KH-W=`}s_nY;)U3Y$+ExmocTH$Zh-1)5%tdc$kUy6-53=B3HvFv7R-N~l8 zgN^kkd*hj(|E@kwST_Cc6Z!3~i;z4 zpb(2-MJRHi1S&#dU`t~pev61MPy@UXHi8N}kvW=j8g&feR eHfjLt6#_OAmCFLWS=m4##{z`=fxa+g1@Qncxus12 literal 0 HcmV?d00001 diff --git a/fuzzing/input/FuzzStun_seed_corpus.zip b/fuzzing/input/FuzzStun_seed_corpus.zip new file mode 100644 index 0000000000000000000000000000000000000000..69726cff02b56598a31b02a013bda726d80b6b13 GIT binary patch literal 1540 zcmWIWW@Zs#0D+5sT%lkFln`Z5U~ns~stPVC&5JKiO-+eU&Mzt`E!GbW;bmZFHvXKn z!Sr*|G$1am;AUWCdBM!U044&!MshH4pct70G*%Utk(qe~r6uu2sfEQQ$$CYJpvk~7S^ww8Ks9SK1~vxH)UuK+s|>TUNCgE2pkqa5y;{z*|HkRC3b{{P zH(mbZd2nmtq6Q5HmZw$L=L5XiIfT!|gcSmP0rClUKb8>X#~dR4Si;Z^@?!$Xj}>c8 zjE}7?I-q&WQ4i>Lp~ubh9yfP9ZeI1cx%qL^`o~Q>fmVw$$fW7(n^;g5-uGl2a3tw1F;_nMa-(~bv)daWlH^{kkd z2J-8lO|OM3fkuLSgx#+J#Q3$ipv;7*_zYlJ|DTbO!3Ilwa)YC?EH$|#zeoX?fH)W! z7rH+bTILLLzxKqhGyl$;aJZ+W^QYF&UBMr+pI-;X*@0T0X&`^pi*7jxO4T6OV)sW3 zk^V44@dqD{bQ#027~~HRBK#r3z_ievQF!IArI$Ze?os`+b>F3(H$i?{+%(nC`&soz z@s^V{O_L6l?tlE&5#*;6zqx%te(F`tyOs!aHOS=w-i%Bl%(yc!Pzf0Pbp%mlW@m^M zundiy4L}(h2DUT?<#l3%u3|ch-#%dBMx7|tt2wHp<9WZa8RvOW+GrEv56kt iO5}J&wemF)RuYvy1H4(;K=H*2g!({3_XEpp1_l85`oFdS literal 0 HcmV?d00001