PDNS_ENABLE_UNIT_TESTS
PDNS_ENABLE_BACKEND_UNIT_TESTS
PDNS_ENABLE_REPRODUCIBLE
+PDNS_ENABLE_FUZZ_TARGETS
PDNS_WITH_SQLITE3
--- /dev/null
+AC_DEFUN([PDNS_ENABLE_FUZZ_TARGETS], [
+ AC_MSG_CHECKING([whether to enable fuzzing targets])
+ AC_ARG_ENABLE([fuzz_targets],
+ AS_HELP_STRING([--enable-fuzz-targets],
+ [enable fuzz targets @<:@default=no@:>@]),
+ [enable_fuzz_targets=$enableval],
+ [enable_fuzz_targets=no]
+ )
+ AC_MSG_RESULT([$enable_fuzz_targets])
+ AM_CONDITIONAL([FUZZ_TARGETS], [test "x$enable_fuzz_targets" != "xno"])
+])
@echo "Run ./configure --enable-unit-tests"
endif
+if FUZZ_TARGETS
+
+LIB_FUZZING_ENGINE ?= standalone_fuzz_target_runner.o
+
+standalone_fuzz_target_runner.o: standalone_fuzz_target_runner.cc
+
+bin_PROGRAMS += \
+ fuzz_dnsdistcache \
+ fuzz_moadnsparser \
+ fuzz_packetcache \
+ fuzz_zoneparsertng
+
+fuzz_targets_libs = \
+ $(LIBCRYPTO_LIBS) \
+ $(LIB_FUZZING_ENGINE)
+fuzz_targets_ldflags = \
+ $(AM_LDFLAGS) \
+ $(DYNLINKFLAGS) \
+ $(LIBCRYPTO_LDFLAGS) \
+ $(FUZZING_LDFLAGS)
+
+# we need the mockup runner to be built, but not linked if a real fuzzing engine is used
+fuzz_targets_deps = standalone_fuzz_target_runner.o
+
+fuzz_moadnsparser_SOURCES = \
+ fuzz_moadnsparser.cc \
+ base32.cc base32.hh \
+ base64.cc base64.hh \
+ dnslabeltext.cc \
+ dnsname.cc dnsname.hh \
+ dnsparser.cc dnsparser.hh \
+ dnsrecords.cc dnsrecords.hh \
+ dnswriter.cc dnswriter.hh \
+ logger.cc logger.hh \
+ misc.cc misc.hh \
+ nsecrecords.cc \
+ qtype.cc qtype.hh \
+ rcpgenerator.cc rcpgenerator.hh \
+ sillyrecords.cc \
+ statbag.cc statbag.hh \
+ unix_utility.cc \
+ utility.hh
+
+fuzz_moadnsparser_DEPENDENCIES = $(fuzz_targets_deps)
+fuzz_moadnsparser_LDFLAGS = $(fuzz_targets_ldflags)
+fuzz_moadnsparser_LDADD = $(fuzz_targets_libs)
+
+fuzz_packetcache_SOURCES = \
+ fuzz_packetcache.cc \
+ dnslabeltext.cc \
+ dnsname.cc dnsname.hh \
+ ednsoptions.cc ednsoptions.hh \
+ misc.cc misc.hh \
+ packetcache.hh \
+ statbag.cc statbag.hh
+
+fuzz_packetcache_DEPENDENCIES = $(fuzz_targets_deps)
+fuzz_packetcache_LDFLAGS = $(fuzz_targets_ldflags)
+fuzz_packetcache_LDADD = $(fuzz_targets_libs)
+
+fuzz_dnsdistcache_SOURCES = \
+ fuzz_dnsdistcache.cc \
+ dnsdist-cache.cc dnsdist-cache.hh \
+ dnsdist-ecs.cc dnsdist-ecs.hh \
+ dnslabeltext.cc \
+ dnsname.cc dnsname.hh \
+ dnsparser.cc dnsparser.hh \
+ dnswriter.cc dnswriter.hh \
+ ednsoptions.cc ednsoptions.hh \
+ ednssubnet.cc ednssubnet.hh \
+ iputils.cc iputils.hh \
+ misc.cc misc.hh \
+ packetcache.hh \
+ qtype.cc qtype.hh
+
+fuzz_dnsdistcache_DEPENDENCIES = $(fuzz_targets_deps)
+fuzz_dnsdistcache_LDFLAGS = $(fuzz_targets_ldflags)
+fuzz_dnsdistcache_LDADD = $(fuzz_targets_libs)
+
+fuzz_zoneparsertng_SOURCES = \
+ fuzz_zoneparsertng.cc \
+ base32.cc base32.hh \
+ base64.cc base64.hh \
+ dnslabeltext.cc \
+ dnsname.cc dnsname.hh \
+ dnsparser.cc dnsparser.hh \
+ dnsrecords.cc dnsrecords.hh \
+ dnswriter.cc dnswriter.hh \
+ logger.cc logger.hh \
+ misc.cc misc.hh \
+ nsecrecords.cc \
+ qtype.cc qtype.hh \
+ rcpgenerator.cc rcpgenerator.hh \
+ sillyrecords.cc \
+ statbag.cc statbag.hh \
+ unix_utility.cc \
+ utility.hh \
+ zoneparser-tng.cc zoneparser-tng.hh
+
+fuzz_zoneparsertng_DEPENDENCIES = $(fuzz_targets_deps)
+fuzz_zoneparsertng_LDFLAGS = $(fuzz_targets_ldflags)
+fuzz_zoneparsertng_LDADD = $(fuzz_targets_libs)
+
+endif
+
dnslabeltext.cc: dnslabeltext.rl
$(AM_V_GEN)$(RAGEL) $< -o dnslabeltext.cc
#include <atomic>
#include <unordered_map>
+
+#include "iputils.hh"
#include "lock.hh"
struct DNSQuestion;
static uint32_t getMinTTL(const char* packet, uint16_t length, bool* seenNoDataSOA);
static uint32_t getKey(const std::string& qname, uint16_t consumed, const unsigned char* packet, uint16_t packetLen, bool tcp);
+ static bool getClientSubnet(const char* packet, unsigned int consumed, uint16_t len, boost::optional<Netmask>& subnet);
private:
std::atomic<uint64_t> d_entriesCount;
};
- static bool getClientSubnet(const char* packet, unsigned int consumed, uint16_t len, boost::optional<Netmask>& subnet);
bool cachedValueMatches(const CacheValue& cachedValue, uint16_t queryFlags, const DNSName& qname, uint16_t qtype, uint16_t qclass, bool tcp, bool dnssecOK, const boost::optional<Netmask>& subnet) const;
uint32_t getShardIndex(uint32_t key) const;
void insertLocked(CacheShard& shard, uint32_t key, CacheValue& newValue);
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dnsdist-cache.hh"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+
+ /* dnsdist's version */
+ try {
+ uint16_t qtype;
+ uint16_t qclass;
+ unsigned int consumed;
+ DNSName qname(reinterpret_cast<const char*>(data), size, sizeof(dnsheader), false, &qtype, &qclass, &consumed);
+ DNSDistPacketCache::getKey(qname.toString(), consumed, data, size, false);
+ boost::optional<Netmask> subnet;
+ DNSDistPacketCache::getClientSubnet(reinterpret_cast<const char*>(data), consumed, size, subnet);
+ }
+ catch(const std::exception& e) {
+ }
+ catch(const PDNSException& e) {
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dnsparser.hh"
+#include "dnsrecords.hh"
+#include "statbag.hh"
+
+StatBag S;
+
+static void init()
+{
+ reportAllTypes();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ static bool initialized = false;
+
+ if (!initialized) {
+ init();
+ initialized = true;
+ }
+
+ try {
+ MOADNSParser moaQuery(true, reinterpret_cast<const char*>(data), size);
+ }
+ catch(const std::exception& e) {
+ }
+ catch(const PDNSException& e) {
+ }
+
+ try {
+ MOADNSParser moaAnswer(false, reinterpret_cast<const char*>(data), size);
+ }
+ catch(const std::exception& e) {
+ }
+ catch(const PDNSException& e) {
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "packetcache.hh"
+#include "statbag.hh"
+
+StatBag S;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+
+ std::string input(reinterpret_cast<const char*>(data), size);
+
+ /* auth's version */
+ try {
+ PacketCache::canHashPacket(input);
+ }
+ catch(const std::exception& e) {
+ }
+ catch(const PDNSException& e) {
+ }
+
+ /* recursor's version */
+ try {
+ uint16_t ecsBegin = 0;
+ uint16_t ecsEnd = 0;
+ PacketCache::canHashPacket(input, &ecsBegin, &ecsEnd);
+ }
+ catch(const std::exception& e) {
+ }
+ catch(const PDNSException& e) {
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dnsname.hh"
+#include "dnsparser.hh"
+#include "dnsrecords.hh"
+#include "statbag.hh"
+#include "zoneparser-tng.hh"
+
+StatBag S;
+
+static void init()
+{
+ reportAllTypes();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ static bool initialized = false;
+
+ if (!initialized) {
+ init();
+ initialized = true;
+ }
+
+ try {
+ std::vector<std::string> lines;
+ std::string tmp(reinterpret_cast<const char*>(data), size);
+ boost::split(lines, tmp, boost::is_any_of("\n"));
+
+ ZoneParserTNG zpt(lines, g_rootdnsname);
+ DNSResourceRecord drr;
+ while (zpt.get(drr)) {
+ }
+ }
+ catch(const std::exception& e) {
+ }
+ catch(const PDNSException& e) {
+ }
+
+ return 0;
+}
--- /dev/null
+
+#include <fstream>
+#include <iostream>
+#include <sys/stat.h>
+#include <vector>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
+extern "C" __attribute__((weak)) int LLVMFuzzerInitialize(int* argc, char*** argv);
+
+int main(int argc, char** argv)
+{
+ std::cerr<<"StandaloneFuzzTargetMain: running "<<(argc-1)<<" inputs"<<std::endl;
+
+ if (LLVMFuzzerInitialize) {
+ LLVMFuzzerInitialize(&argc, &argv);
+ }
+
+ for (int i = 1; i < argc; i++) {
+
+ struct stat st;
+ if (stat(argv[i], &st) || !S_ISREG(st.st_mode)) {
+ std::cerr<<"Skipping non-regular file: "<<std::string(argv[i])<<std::endl;
+ continue;
+ }
+
+ std::cerr<<"Running: "<<std::string(argv[i])<<std::endl;
+
+ std::ifstream file(argv[i], std::ios::binary);
+ file.seekg(0, std::ios::end);
+ size_t fileSize = file.tellg();
+ file.seekg(0, std::ios::beg);
+
+ std::vector<char> buffer;
+ buffer.resize(fileSize);
+
+ file.read(reinterpret_cast<char*>(buffer.data()), fileSize);
+
+ if (file.fail()) {
+ file.close();
+ throw std::runtime_error("Error reading fuzzing input from file '" + std::string(argv[i]) + '"');
+ }
+
+ file.close();
+
+ LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t*>(buffer.data()), fileSize);
+
+ std::cerr<<"Done: '"<<std::string(argv[i])<<"': ("<<fileSize<<" bytes)"<<std::endl;
+ }
+
+ return 0;
+}