diff --git a/FUZZING.MD b/FUZZING.MD new file mode 100644 index 000000000..2ee39f0be --- /dev/null +++ b/FUZZING.MD @@ -0,0 +1,33 @@ +### Export Flags + +``` +export CC=clang +export CXX=clang++ +export LIB_FUZZING_ENGINE=-fsanitize=fuzzer +export CFLAGS="-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" +export CXXFLAGS="$CFLAGS" +export LDFLAGS="$CFLAGS" +``` + +### Compile Guide + +Note: While compiling fuzzing suite, Don't use bloat libraries. + +``` +./configure --disable-ffmpeg --disable-ssl --disable-speex-aec --disable-speex-codec --disable-g7221-codec --disable-gsm-codec --disable-ilbc-codec --disable-resample --disable-libsrtp --disable-libwebrtc --disable-libyuv + +make dep +make -j$(nproc) +make fuzz +``` + + +### Run + +``` +cd tests/fuzz +mkdir cov-json +unzip seed/fuzz-json_seed_corpus.zip +./fuzz-json cov-json/ fuzz-json_seed_corpus/ +``` + diff --git a/Makefile b/Makefile index 2b1f2f655..636b0c2b5 100644 --- a/Makefile +++ b/Makefile @@ -124,6 +124,9 @@ pjsua-test: cmp_wav cmp_wav: cd tests/pjsua/tools && make +fuzz: + cd tests/fuzz && make + install: mkdir -p $(DESTDIR)$(libdir)/ if [ "$(PJ_EXCLUDE_PJSUA2)x" = "x" ] ; then \ diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile new file mode 100644 index 000000000..31abeb978 --- /dev/null +++ b/tests/fuzz/Makefile @@ -0,0 +1,32 @@ +#Modify this to point to the PJSIP location. +PJBASE=../../ + +include $(PJBASE)/build.mak + +TARGET=Fuzzing + +JSON=fuzz-json +XML=fuzz-xml +SDP=fuzz-sdp +STUN=fuzz-stun +SIP=fuzz-sip + +EXTFLAGS=-Wall -Werror + +all: $(TARGET) + +$(TARGET): + $(CC) $(PJ_CFLAGS) $(EXTFLAGS) -c $(JSON).c + $(CC) $(PJ_CFLAGS) $(EXTFLAGS) -c $(XML).c + $(CC) $(PJ_CFLAGS) $(EXTFLAGS) -c $(SDP).c + $(CC) $(PJ_CFLAGS) $(EXTFLAGS) -c $(STUN).c + $(CC) $(PJ_CFLAGS) $(EXTFLAGS) -c $(SIP).c + + $(CXX) $(PJ_CFLAGS) -o $(JSON) $(JSON).o $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS) $(LIB_FUZZING_ENGINE) + $(CXX) $(PJ_CFLAGS) -o $(XML) $(XML).o $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS) $(LIB_FUZZING_ENGINE) + $(CXX) $(PJ_CFLAGS) -o $(SDP) $(SDP).o $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS) $(LIB_FUZZING_ENGINE) + $(CXX) $(PJ_CFLAGS) -o $(STUN) $(STUN).o $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS) $(LIB_FUZZING_ENGINE) + $(CXX) $(PJ_CFLAGS) -o $(SIP) $(SIP).o $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS) $(LIB_FUZZING_ENGINE) + +clean: + rm $(JSON) $(XML) $(SDP) $(STUN) $(SIP) *.o diff --git a/tests/fuzz/fuzz-json.c b/tests/fuzz/fuzz-json.c new file mode 100644 index 000000000..c2449db27 --- /dev/null +++ b/tests/fuzz/fuzz-json.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define kMinInputLength 10 +#define kMaxInputLength 5120 + +pj_pool_factory *mem; + +int Json_parse(char *DataFx,size_t Size){ + + int ret = 0; + pj_pool_t *pool; + pj_json_elem *elem; + pj_json_err_info err; + + pool = pj_pool_create(mem, "json", 1000, 1000, NULL); + + elem = pj_json_parse(pool, DataFx,(unsigned *)&Size, &err); + + if (!elem) + ret = 1; + + pj_pool_release(pool); + + return ret; +} + +extern int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{/*pjproject/pjlib-util/src/pjlib-util-test/json_test.c*/ + + if (Size < kMinInputLength || Size > kMaxInputLength){ + return 1; + } + +/*Add Extra byte */ + char *DataFx; + DataFx = (char *)calloc((Size+1),sizeof(char)); + memcpy((void *)DataFx,(void *)Data,Size); + +/*init*/ + int ret = 0; + pj_caching_pool caching_pool; + mem = &caching_pool.factory; + + pj_log_set_level(0); + + ret = pj_init(); + ret = pjlib_util_init(); + + pj_dump_config(); + pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 0); + +/*Calls*/ + ret = Json_parse(DataFx,Size); + + free(DataFx); + + return ret; +} diff --git a/tests/fuzz/fuzz-sdp.c b/tests/fuzz/fuzz-sdp.c new file mode 100644 index 000000000..31749e797 --- /dev/null +++ b/tests/fuzz/fuzz-sdp.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include +#include + +#include +#include + +#define kMinInputLength 10 +#define kMaxInputLength 5120 + +pj_pool_factory *mem; + +int sdp_parser(char *DataFx,size_t Size){ + + int ret = 0; + pj_pool_t *pool; + pjmedia_sdp_session *sdp; + pj_status_t status; + + pool = pj_pool_create(mem, "sdp_neg_test", 4000, 4000, NULL); + + status = pjmedia_sdp_parse(pool, DataFx, Size,&sdp); + + if (status != PJ_SUCCESS){ + ret = 1; + goto end; + } + + status = pjmedia_sdp_validate(sdp); + +end: + pj_pool_release(pool); + + return ret; +} + +extern int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{/*pjproject/pjmedia/src/test/sdp_neg_test.c*/ + + if (Size < kMinInputLength || Size > kMaxInputLength){ + return 1; + } + +/*Add Extra byte */ + char *DataFx; + DataFx = (char *)calloc((Size+1),sizeof(char)); + memcpy((void *)DataFx,(void *)Data,Size); + +/*init*/ + int ret = 0; + pj_caching_pool caching_pool; + pj_pool_t *pool; + + pj_init(); + pj_caching_pool_init(&caching_pool, &pj_pool_factory_default_policy, 0); + pool = pj_pool_create(&caching_pool.factory, "test", 1000, 512, NULL); + + pj_log_set_level(0); + + mem = &caching_pool.factory; + + pjmedia_event_mgr_create(pool, 0, NULL); + +/*Call*/ + ret = sdp_parser(DataFx,Size); + +/*Free*/ + pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance()); + pj_pool_release(pool); + pj_caching_pool_destroy(&caching_pool); + + free(DataFx); + return ret; +} diff --git a/tests/fuzz/fuzz-sip.c b/tests/fuzz/fuzz-sip.c new file mode 100644 index 000000000..30c868c23 --- /dev/null +++ b/tests/fuzz/fuzz-sip.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + + +pjsip_endpoint *endpt; +pj_caching_pool caching_pool; + +#define POOL_SIZE 8000 +#define PJSIP_TEST_MEM_SIZE (2*1024*1024) + +#define kMinInputLength 10 +#define kMaxInputLength 5120 + +int sipParser(char *DataFx,size_t Size){ + + int ret = 0; + pj_pool_t *pool; + pjsip_msg *parsed_msg = NULL; + pjsip_parser_err_report err_list; + + pool = pjsip_endpt_create_pool(endpt, NULL, POOL_SIZE, POOL_SIZE); + + + pj_list_init(&err_list); + + parsed_msg = pjsip_parse_msg(pool, DataFx, Size, &err_list); + + if (parsed_msg == NULL) + ret = 1; + + pjsip_endpt_release_pool(endpt, pool); + + return ret; +} + +extern int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{/*/home/Ez/project/pjproject/pjsip/src/test/msg_test.c*/ + + if (Size < kMinInputLength || Size > kMaxInputLength){ + return 1; + } + +/*Add Extra byte */ + char *DataFx; + DataFx = (char *)calloc((Size+1),sizeof(char)); + memcpy((void *)DataFx,(void *)Data,Size); + + +/*init*/ + pj_status_t rc; + //pj_status_t status; + + pj_log_set_level(0); + + rc=pj_init(); + rc=pjlib_util_init(); + + pj_dump_config(); + + pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, + PJSIP_TEST_MEM_SIZE ); + + rc = pjsip_endpt_create(&caching_pool.factory, "endpt", &endpt); + + /* Start transaction layer module. */ + rc = pjsip_tsx_layer_init_module(endpt); + + rc = pjsip_loop_start(endpt, NULL); + +/*Calls*/ + rc = sipParser(DataFx,Size); + + pjsip_endpt_destroy(endpt); + pj_caching_pool_destroy(&caching_pool); + + free(DataFx); + + return rc; +} diff --git a/tests/fuzz/fuzz-stun.c b/tests/fuzz/fuzz-stun.c new file mode 100644 index 000000000..fecd372c9 --- /dev/null +++ b/tests/fuzz/fuzz-stun.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define kMinInputLength 10 +#define kMaxInputLength 5120 + +pj_pool_factory *mem; + +int stun_parse(char *DataFx,size_t Size){ + int ret = 0; + pj_pool_t *pool; + pj_stun_msg *msg; + pj_status_t status; + + pool = pj_pool_create(mem, "decode_test", 1024, 1024, NULL); + + status = pj_stun_msg_decode(pool, (pj_uint8_t*)DataFx,Size, + PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, + &msg, NULL, NULL); + + if(status) + ret = 1; + + pj_pool_release(pool); + + return ret; +} + +extern int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{/*pjproject/pjnath/src/pjnath-test/stun.c*/ + + if (Size < kMinInputLength || Size > kMaxInputLength){ + return 1; + } + +/*Add Extra byte */ + char *DataFx; + DataFx = (char *)calloc((Size+1),sizeof(char)); + memcpy((void *)DataFx,(void *)Data,Size); + +/*init*/ + int ret = 0; + pj_caching_pool caching_pool; + + mem = &caching_pool.factory; + + pj_log_set_level(0); + + pj_init(); + + pj_dump_config(); + pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 0 ); + + pjlib_util_init(); + pjnath_init(); + +/*call*/ + ret = stun_parse(DataFx,Size); + + free(DataFx); + return ret; +} diff --git a/tests/fuzz/fuzz-xml.c b/tests/fuzz/fuzz-xml.c new file mode 100644 index 000000000..815060ea2 --- /dev/null +++ b/tests/fuzz/fuzz-xml.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include + +#include + +#define kMinInputLength 10 +#define kMaxInputLength 5120 + +pj_pool_factory *mem; + +int XML_parse(char *DataFx,size_t Size){ + + int ret = 0; + pj_pool_t *pool; + pj_xml_node *root; + + pool = pj_pool_create(mem, "xml", 4096, 1024, NULL); + + root = pj_xml_parse(pool, DataFx, Size); + + if (!root) + ret += 1; + + pj_pool_release(pool); + + return ret; +} + +extern int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{/*pjproject/pjlib-util/src/pjlib-util-test/xml.c*/ + + if (Size < kMinInputLength || Size > kMaxInputLength){ + return 1; + } + +/*Add Extra byte */ + char *DataFx; + DataFx = (char *)calloc((Size+1),sizeof(char)); + memcpy((void *)DataFx,(void *)Data,Size); + +/*init*/ + int ret = 0; + pj_caching_pool caching_pool; + mem = &caching_pool.factory; + + pj_log_set_level(0); + + ret = pj_init(); + ret = pjlib_util_init(); + + pj_dump_config(); + pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 0 ); + +/*Call*/ + ret = XML_parse(DataFx,Size); + + free(DataFx); + + return ret; +} diff --git a/tests/fuzz/seed/fuzz-json_seed_corpus.zip b/tests/fuzz/seed/fuzz-json_seed_corpus.zip new file mode 100644 index 000000000..3b372c454 Binary files /dev/null and b/tests/fuzz/seed/fuzz-json_seed_corpus.zip differ diff --git a/tests/fuzz/seed/fuzz-sdp_seed_corpus.zip b/tests/fuzz/seed/fuzz-sdp_seed_corpus.zip new file mode 100644 index 000000000..88361b4eb Binary files /dev/null and b/tests/fuzz/seed/fuzz-sdp_seed_corpus.zip differ diff --git a/tests/fuzz/seed/fuzz-sip_seed_corpus.zip b/tests/fuzz/seed/fuzz-sip_seed_corpus.zip new file mode 100644 index 000000000..a9ed40b7d Binary files /dev/null and b/tests/fuzz/seed/fuzz-sip_seed_corpus.zip differ diff --git a/tests/fuzz/seed/fuzz-stun_seed_corpus.zip b/tests/fuzz/seed/fuzz-stun_seed_corpus.zip new file mode 100644 index 000000000..4d1545c67 Binary files /dev/null and b/tests/fuzz/seed/fuzz-stun_seed_corpus.zip differ diff --git a/tests/fuzz/seed/fuzz-xml_seed_corpus.zip b/tests/fuzz/seed/fuzz-xml_seed_corpus.zip new file mode 100644 index 000000000..92d1bd064 Binary files /dev/null and b/tests/fuzz/seed/fuzz-xml_seed_corpus.zip differ