blob: c55968c114a8623bbcbe484be126acb0381b14da [file] [log] [blame]
diff -Nur ORIG.bind-9.11.11/bin/named/fuzz.c bind-9.11.11/bin/named/fuzz.c
--- ORIG.bind-9.11.11/bin/named/fuzz.c 2019-09-09 16:48:35.000000000 +0200
+++ bind-9.11.11/bin/named/fuzz.c 2019-10-10 17:12:21.797312932 +0200
@@ -36,10 +36,6 @@
#include <unistd.h>
#include <pthread.h>
-#ifndef __AFL_LOOP
-#error To use American Fuzzy Lop you have to set CC to afl-clang-fast!!!
-#endif
-
/*
* We are using pthreads directly because we might be using it with unthreaded
* version of BIND, where all thread functions are mocks. Since AFL for now only
@@ -317,7 +313,6 @@
* It's here just for the signature, that's how AFL detects if it's
* a 'persistent mode' binary.
*/
- __AFL_LOOP(0);
return (NULL);
}
@@ -433,6 +428,7 @@
void
named_fuzz_notify(void) {
+#if 0
#ifdef ENABLE_AFL
if (getenv("AFL_CMIN")) {
ns_server_flushonshutdown(ns_g_server, false);
@@ -440,7 +436,9 @@
return;
}
+#if 0
raise(SIGSTOP);
+#endif
RUNTIME_CHECK(pthread_mutex_lock(&mutex) == 0);
@@ -449,12 +447,12 @@
RUNTIME_CHECK(pthread_cond_signal(&cond) == 0);
RUNTIME_CHECK(pthread_mutex_unlock(&mutex) == 0);
#endif /* ENABLE_AFL */
+#endif
}
void
named_fuzz_setup(void) {
-#ifdef ENABLE_AFL
- if (getenv("__AFL_PERSISTENT") || getenv("AFL_CMIN")) {
+#if 0
pthread_t thread;
void *(fn) = NULL;
@@ -478,6 +476,5 @@
RUNTIME_CHECK(pthread_mutex_init(&mutex, NULL) == 0);
RUNTIME_CHECK(pthread_cond_init(&cond, NULL) == 0);
RUNTIME_CHECK(pthread_create(&thread, NULL, fn, NULL) == 0);
- }
#endif /* ENABLE_AFL */
}
diff -Nur ORIG.bind-9.11.11/bin/named/main.c bind-9.11.11/bin/named/main.c
--- ORIG.bind-9.11.11/bin/named/main.c 2019-09-09 16:48:35.000000000 +0200
+++ bind-9.11.11/bin/named/main.c 2019-10-10 17:12:14.509316056 +0200
@@ -1401,13 +1401,288 @@
}
#endif /* HAVE_LIBSCF */
+
+#include <named/globals.h>
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <pthread.h>
+#include <sched.h>
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <libhfcommon/util.h>
+#include <libhfuzz/libhfuzz.h>
+
+static void enter_namespaces(void)
+{
+ if (linuxEnterNs(CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWIPC) == false) {
+ exit(1);
+ }
+ if (linuxIfaceUp("lo") == false) {
+ exit(1);
+ }
+ if (linuxMountTmpfs("/tmp") == false) {
+ exit(1);
+ }
+}
+
+static size_t rlen = 0;
+static const uint8_t* rbuf = NULL;
+
+__attribute__((no_sanitize("memory")))
+__attribute__((no_sanitize("address"))) static void*
+bind_thr(void* unused __attribute__((unused)))
+{
+ while (!ns_g_run_done) {
+ usleep(100000);
+ }
+
+ int myfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+ if (myfd == -1) {
+ perror("socket");
+ exit(1);
+ }
+ int val = 1;
+ if (setsockopt(myfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) {
+ perror("setsockopt(SO_REUSEADDR)");
+ }
+
+ const struct sockaddr_in saddr = {
+ .sin_family = AF_INET,
+ .sin_port = htons(53),
+ .sin_addr.s_addr = inet_addr("127.0.0.2"),
+ };
+ if (bind(myfd, &saddr, sizeof(saddr)) == -1) {
+ perror("bind");
+ exit(1);
+ }
+
+ if (listen(myfd, SOMAXCONN) == -1) {
+ perror("listen");
+ exit(1);
+ }
+
+ for (;;) {
+ struct sockaddr_in cli;
+ socklen_t cli_len = sizeof(cli);
+
+ int nfd = accept(myfd, &cli, &cli_len);
+ if (nfd == -1) {
+ perror("accept");
+ exit(1);
+ }
+
+ static char b[1024 * 1024];
+ ssize_t sz = recv(nfd, b, sizeof(b), 0);
+ if (sz <= 0) {
+ perror("recv");
+ _exit(1);
+ }
+ if (sz < 4) {
+ close(nfd);
+ continue;
+ }
+ if (rlen < 1) {
+ close(nfd);
+ continue;
+ }
+
+ /* It's a response, so set QR bit to 1 */
+ uint8_t qr = rbuf[0] | 0x80;
+
+ uint16_t t_l = htons(rlen + 2);
+ const struct iovec iov[] = {
+ {
+ .iov_base = &t_l,
+ .iov_len = sizeof(t_l),
+ },
+ {
+ .iov_base = &b[2],
+ .iov_len = 2,
+ },
+ {
+ .iov_base = &qr,
+ .iov_len = 1,
+ },
+ {
+ .iov_base = (void*)&rbuf[1],
+ .iov_len = rlen - 1,
+ },
+ };
+
+ if (writev(nfd, iov, 4) == -1) {
+ perror("writev() failed");
+ }
+
+ close(nfd);
+ }
+
+ return NULL;
+}
+
+static void rndloop(int sock)
+{
+ const struct sockaddr_in bsaddr = {
+ .sin_family = AF_INET,
+ .sin_port = htons(0),
+ .sin_addr.s_addr = htonl((((uint32_t)util_rnd64()) & 0x00FFFFFF) | 0x7F000000),
+ };
+ if (bind(sock, (const struct sockaddr*)&bsaddr, sizeof(bsaddr)) == -1) {
+ perror("bind");
+ }
+}
+
+__attribute__((no_sanitize("memory")))
+__attribute__((no_sanitize("address"))) static void*
+connect_thr(void* unused __attribute__((unused)))
+{
+ while (!ns_g_run_done) {
+ usleep(100000);
+ }
+
+ for (;;) {
+ int myfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+ if (myfd == -1) {
+ perror("socket");
+ exit(1);
+ }
+ int val = 1;
+ if (setsockopt(myfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) {
+ perror("setsockopt(SO_REUSEADDR)");
+ }
+
+ rndloop(myfd);
+
+ const struct sockaddr_in saddr = {
+ .sin_family = AF_INET,
+ .sin_port = htons(53),
+ .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
+ };
+ if (connect(myfd, &saddr, sizeof(saddr)) == -1) {
+ close(myfd);
+ continue;
+ }
+
+ const uint8_t* buf;
+ size_t len;
+
+ if (ns_g_fuzz_type == ns_fuzz_client) {
+ HF_ITER(&buf, &len);
+
+ rlen = 0;
+ rbuf = NULL;
+
+ if (len < 32) {
+ close(myfd);
+ continue;
+ }
+
+ uint32_t tmplen = *((const uint32_t*)buf);
+
+ buf = &buf[sizeof(uint32_t)];
+ len -= sizeof(uint32_t);
+
+ tmplen %= len;
+
+ rbuf = &buf[tmplen];
+ rlen = len - tmplen;
+ len = tmplen;
+ } else {
+ static const uint8_t qbuf[] = {
+ 0x88, 0x0c, 0x01, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x0a, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+ 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00
+ };
+ buf = qbuf;
+ len = sizeof(qbuf);
+ HF_ITER(&rbuf, &rlen);
+ }
+
+ uint16_t t_l = htons(len);
+ const struct iovec iov[] = {
+ {
+ .iov_base = &t_l,
+ .iov_len = sizeof(t_l),
+ },
+ {
+ .iov_base = (void*)buf,
+ .iov_len = len,
+ },
+ };
+
+ if (writev(myfd, iov, 2) == -1) {
+ perror("write");
+ close(myfd);
+ continue;
+ }
+
+ if (shutdown(myfd, SHUT_WR) == -1) {
+ if (errno == ENOTCONN) {
+ close(myfd);
+ continue;
+ }
+ perror("shutdown");
+ _exit(1);
+ }
+
+ uint8_t b[1024 * 512];
+ while (recv(myfd, b, sizeof(b), 0) > 0)
+ ;
+ close(myfd);
+ }
+}
+
+static void launch_thr(void)
+{
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 1024 * 1024 * 4);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ pthread_t t;
+ if (pthread_create(&t, &attr, bind_thr, NULL) < 0) {
+ perror("pthread_create(bind_thr)");
+ exit(1);
+ }
+
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 1024 * 1024 * 4);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ if (pthread_create(&t, &attr, connect_thr, NULL) < 0) {
+ perror("pthread_create(connect_thr)");
+ exit(1);
+ }
+}
+
/* main entry point, possibly hooked */
-int
-main(int argc, char *argv[]) {
- isc_result_t result;
+int main(int argc, char* argv[])
+{
+ if (!getenv("NO_FUZZ")) {
+ ns_g_fuzz_named_addr = "127.0.0.1:53";
+ ns_g_fuzz_type = ns_fuzz_client;
+ enter_namespaces();
+ launch_thr();
+ }
+
+ isc_result_t result;
#ifdef HAVE_LIBSCF
- char *instance = NULL;
+ char *instance = NULL;
#endif
#ifdef HAVE_GPERFTOOLS_PROFILER
diff -Nur ORIG.bind-9.11.11/compile.sh bind-9.11.11/compile.sh
--- ORIG.bind-9.11.11/compile.sh 1970-01-01 01:00:00.000000000 +0100
+++ bind-9.11.11/compile.sh 2019-10-10 17:01:02.537600110 +0200
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+set -ex
+
+export CC="$HOME"/src/honggfuzz/hfuzz_cc/hfuzz-clang
+export CXX="$HOME"/src/honggfuzz/hfuzz_cc/hfuzz-clang++
+export CFLAGS="-fsanitize=address -Wno-shift-negative-value -Wno-logical-not-parentheses -g -ggdb -O0 -D__AFL_COMPILER"
+./configure \
+ --prefix="$HOME"/fuzz/bind/dist/ \
+ --without-gssapi \
+ --disable-chroot \
+ --disable-linux-caps \
+ --without-libtool \
+ --enable-epoll \
+ --enable-fuzzing=afl \
+ --disable-backtrace \
+ --with-openssl=yes
+
+make clean
+make -j$(nproc)
diff -Nur ORIG.bind-9.11.11/lib/dns/request.c bind-9.11.11/lib/dns/request.c
--- ORIG.bind-9.11.11/lib/dns/request.c 2019-09-09 16:48:35.000000000 +0200
+++ bind-9.11.11/lib/dns/request.c 2019-10-10 16:58:01.385685064 +0200
@@ -749,8 +749,8 @@
isc_result_t result;
isc_mem_t *mctx;
dns_messageid_t id;
- bool tcp = false;
- bool newtcp = false;
+ bool tcp = true;
+ bool newtcp = true;
bool share = false;
isc_region_t r;
bool connected = false;
@@ -997,6 +997,8 @@
REQUIRE(requestp != NULL && *requestp == NULL);
REQUIRE(timeout > 0);
+ options |= DNS_REQUESTOPT_TCP;
+
mctx = requestmgr->mctx;
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia");
@@ -1140,11 +1142,13 @@
req_render(dns_message_t *message, isc_buffer_t **bufferp,
unsigned int options, isc_mem_t *mctx)
{
+ options |= DNS_REQUESTOPT_TCP;
+
isc_buffer_t *buf1 = NULL;
isc_buffer_t *buf2 = NULL;
isc_result_t result;
isc_region_t r;
- bool tcp = false;
+ bool tcp = true;
dns_compress_t cctx;
bool cleanup_cctx = false;
diff -Nur ORIG.bind-9.11.11/lib/dns/resolver.c bind-9.11.11/lib/dns/resolver.c
--- ORIG.bind-9.11.11/lib/dns/resolver.c 2019-09-09 16:48:35.000000000 +0200
+++ bind-9.11.11/lib/dns/resolver.c 2019-10-10 16:46:22.370051194 +0200
@@ -1691,6 +1691,7 @@
}
query->mctx = fctx->mctx;
query->options = options;
+ query->options = options | DNS_FETCHOPT_TCP;
query->attributes = 0;
query->sends = 0;
query->connects = 0;
diff -Nur ORIG.bind-9.11.11/lib/isc/random.c bind-9.11.11/lib/isc/random.c
--- ORIG.bind-9.11.11/lib/isc/random.c 2019-09-09 16:48:35.000000000 +0200
+++ bind-9.11.11/lib/isc/random.c 2019-10-10 16:51:36.281886984 +0200
@@ -126,6 +126,9 @@
void
isc_random_get(uint32_t *val) {
+ *val = 1;
+ return;
+
REQUIRE(val != NULL);
initialize();
@@ -153,6 +156,8 @@
uint32_t
isc_random_jitter(uint32_t max, uint32_t jitter) {
+ return 1;
+
uint32_t rnd;
REQUIRE(jitter < max || (jitter == 0 && max == 0));
@@ -306,6 +311,7 @@
static inline uint16_t
chacha_getuint16(isc_rng_t *rng) {
+ return 1;
uint16_t val;
REQUIRE(VALID_RNG(rng));
@@ -364,6 +370,8 @@
uint16_t
isc_rng_random(isc_rng_t *rng) {
+ return 1;
+
uint16_t result;
REQUIRE(VALID_RNG(rng));
@@ -382,6 +390,7 @@
uint16_t
isc_rng_uniformrandom(isc_rng_t *rng, uint16_t upper_bound) {
+
uint16_t min, r;
REQUIRE(VALID_RNG(rng));
@@ -389,6 +398,8 @@
if (upper_bound < 2)
return (0);
+ return 1;
+
/*
* Ensure the range of random numbers [min, 0xffff] be a multiple of
* upper_bound and contain at least a half of the 16 bit range.