From patchwork Tue Oct 13 13:36:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Petr_=C5=A0tetiar?= X-Patchwork-Id: 1381596 X-Patchwork-Delegate: ynezz@true.cz Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=true.cz Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=BUS2q3dy; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C9c7t2w9Yz9sTr for ; Wed, 14 Oct 2020 00:38:34 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=QFKbw6pENWbK5fHeDTavf4GdxCx8NktXOwCBue0HVxM=; b=BUS2q3dyj/9NZ25X1jeabrM/X JJLSRsTgUhxifkbvyqK3QGK3oA6/amFTJxk8OxrEZYZRvfaFbaEVKAyIVVNhhmZZZtf9/c7q9FMBV 3CXhoqJCqwglXxlCeEjVHlkjGnUCRRN332rvZRLhT7sP6g9kqRaDIFOd8BTtB0h65B03RXJowlK5R Yva38McEJPv1qOpYeedhQqIZD9s3cMY5FsdHC302ZfTIi7Xb6ZS9jtipSybXO7DGuW3UVG9zfY5Vb bcz5NIS1MoGqQVxLVbjxaxjgYcyCaDAtohnrIrz+RvFDdZ+o6lAhITjpfqp/mnROT7e/X9wc3Sdxn p5jOLX1XA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kSKUG-0006L5-4T; Tue, 13 Oct 2020 13:37:08 +0000 Received: from smtp-out.xnet.cz ([178.217.244.18]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kSKTj-00069n-1F for openwrt-devel@lists.openwrt.org; Tue, 13 Oct 2020 13:36:38 +0000 Received: from meh.true.cz (meh.true.cz [108.61.167.218]) (Authenticated sender: petr@true.cz) by smtp-out.xnet.cz (Postfix) with ESMTPSA id 9BDBC1870A; Tue, 13 Oct 2020 15:36:26 +0200 (CEST) Received: by meh.true.cz (OpenSMTPD) with ESMTP id 4f1b6115; Tue, 13 Oct 2020 15:36:10 +0200 (CEST) From: =?utf-8?q?Petr_=C5=A0tetiar?= To: openwrt-devel@lists.openwrt.org Subject: [PATCH mdnsd 06/10] tests: add libFuzzer based fuzzing Date: Tue, 13 Oct 2020 15:36:17 +0200 Message-Id: <20201013133621.27088-7-ynezz@true.cz> In-Reply-To: <20201013133621.27088-1-ynezz@true.cz> References: <20201013133621.27088-1-ynezz@true.cz> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201013_093635_329285_247DD156 X-CRM114-Status: GOOD ( 22.87 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Petr_=C5=A0tetiar?= Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org LibFuzzer is in-process, coverage-guided, evolutionary fuzzing engine. LibFuzzer is linked with the library under test, and feeds fuzzed inputs to the library via a specific fuzzing entrypoint (aka "target function"); the fuzzer then tracks which areas of the code are reached, and generates mutations on the corpus of input data in order to maximize the code coverage. So lets use libFuzzer to fuzz dns_handle_packet for the start. Ref: https://llvm.org/docs/LibFuzzer.html Signed-off-by: Petr Štetiar --- CMakeLists.txt | 5 ++++ tests/CMakeLists.txt | 3 ++ tests/fuzz/CMakeLists.txt | 18 ++++++++++++ tests/fuzz/dict/mdns.dict | 6 ++++ tests/fuzz/inputs/query_qu.pcap | Bin 0 -> 128 bytes tests/fuzz/test-fuzz.c | 48 ++++++++++++++++++++++++++++++++ 6 files changed, 80 insertions(+) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/fuzz/CMakeLists.txt create mode 100644 tests/fuzz/dict/mdns.dict create mode 100644 tests/fuzz/inputs/query_qu.pcap create mode 100644 tests/fuzz/test-fuzz.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e08720327b7c..80d1cf5be352 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,11 @@ TARGET_LINK_LIBRARIES(umdns-lib ${LIBS}) ADD_EXECUTABLE(umdns main.c) TARGET_LINK_LIBRARIES(umdns umdns-lib) +IF(UNIT_TESTING) + ENABLE_TESTING() + ADD_SUBDIRECTORY(tests) +ENDIF() + INSTALL(TARGETS umdns RUNTIME DESTINATION sbin ) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000000..02b121c7b8ec --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,3 @@ +IF(CMAKE_C_COMPILER_ID STREQUAL "Clang") + ADD_SUBDIRECTORY(fuzz) +ENDIF() diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt new file mode 100644 index 000000000000..e2f98730de05 --- /dev/null +++ b/tests/fuzz/CMakeLists.txt @@ -0,0 +1,18 @@ +FILE(GLOB test_cases "test-*.c") + +MACRO(ADD_FUZZER_TEST name) + ADD_EXECUTABLE(${name} ${name}.c) + TARGET_COMPILE_OPTIONS(${name} PRIVATE -g -O1 -fno-omit-frame-pointer -fsanitize=fuzzer,address,leak,undefined) + TARGET_INCLUDE_DIRECTORIES(${name} PRIVATE ${PROJECT_SOURCE_DIR}) + TARGET_LINK_OPTIONS(${name} PRIVATE -stdlib=libc++ -fsanitize=fuzzer,address,leak,undefined) + TARGET_LINK_LIBRARIES(${name} umdns-lib-san ${LIBS}) + ADD_TEST( + NAME ${name} + COMMAND ${name} -max_len=256 -timeout=10 -max_total_time=300 ${CMAKE_CURRENT_SOURCE_DIR}/corpus + ) +ENDMACRO(ADD_FUZZER_TEST) + +FOREACH(test_case ${test_cases}) + GET_FILENAME_COMPONENT(test_case ${test_case} NAME_WE) + ADD_FUZZER_TEST(${test_case}) +ENDFOREACH(test_case) diff --git a/tests/fuzz/dict/mdns.dict b/tests/fuzz/dict/mdns.dict new file mode 100644 index 000000000000..f8f80c13a521 --- /dev/null +++ b/tests/fuzz/dict/mdns.dict @@ -0,0 +1,6 @@ +"\x0c" +"\x78" +"\xc0\xb0" +"\x80\x01" +"." +"_" diff --git a/tests/fuzz/inputs/query_qu.pcap b/tests/fuzz/inputs/query_qu.pcap new file mode 100644 index 0000000000000000000000000000000000000000..b1857a963a4f3efb0af43ee6714d96f07e04c198 GIT binary patch literal 128 zcmca|c+)~A1{MYcU}0bca;#!n84i^_!)B~WL$V-uz3}#=K0TqLkg8^rJacWUnW^!sVdwfb>v2Jk+OMGcc0c%cv Ma$*hx15X1Z0A`FJT>t<8 literal 0 HcmV?d00001 diff --git a/tests/fuzz/test-fuzz.c b/tests/fuzz/test-fuzz.c new file mode 100644 index 000000000000..ca6caa1ee17a --- /dev/null +++ b/tests/fuzz/test-fuzz.c @@ -0,0 +1,48 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "dns.h" +#include "cache.c" +#include "interface.h" + +int cfg_proto = 0; +int cfg_no_subnet = 0; + +static void fuzz_dns_handle_packet(uint8_t *input, size_t size) +{ + struct sockaddr from; + struct interface iface; + struct cache_service *s, *t; + + memset(&from, 0, sizeof(from)); + memset(&iface, 0, sizeof(iface)); + + cache_init(); + dns_handle_packet(&iface, &from, 1922, input, size); + + avl_for_each_element_safe(&services, s, avl, t) + cache_service_free(s); +} + +int LLVMFuzzerTestOneInput(const uint8_t *input, size_t size) +{ + uint8_t *buf = calloc(1, size); + if (!buf) + return 0; + + memcpy(buf, input, size); + fuzz_dns_handle_packet(buf, size); + free(buf); + + return 0; +}