1diff -Nur ORIG.bind-9.13.5-W1/bin/named/main.c bind-9.13.5-W1/bin/named/main.c 2--- ORIG.bind-9.13.5-W1/bin/named/main.c 2018-12-17 23:27:19.000000000 +0100 3+++ bind-9.13.5-W1/bin/named/main.c 2019-01-11 17:37:23.537289679 +0100 4@@ -1311,11 +1311,285 @@ 5 } 6 #endif /* HAVE_LIBSCF */ 7 8+#include <named/globals.h> 9+ 10+#include <arpa/inet.h> 11+#include <errno.h> 12+#include <fcntl.h> 13+#include <net/if.h> 14+#include <net/route.h> 15+#include <netinet/ip6.h> 16+#include <netinet/tcp.h> 17+#include <pthread.h> 18+#include <sched.h> 19+#include <sys/ioctl.h> 20+#include <sys/resource.h> 21+#include <sys/socket.h> 22+#include <sys/stat.h> 23+#include <sys/time.h> 24+#include <sys/types.h> 25+#include <sys/uio.h> 26+#include <sys/wait.h> 27+#include <unistd.h> 28+ 29+#include <libhfcommon/util.h> 30+#include <libhfuzz/libhfuzz.h> 31+ 32+static void enter_namespaces(void) 33+{ 34+ if (linuxEnterNs(CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWIPC) == false) { 35+ exit(1); 36+ } 37+ if (linuxIfaceUp("lo") == false) { 38+ exit(1); 39+ } 40+ if (linuxMountTmpfs("/tmp") == false) { 41+ exit(1); 42+ } 43+} 44+ 45+static size_t rlen = 0; 46+static const uint8_t* rbuf = NULL; 47+ 48+__attribute__((no_sanitize("memory"))) 49+__attribute__((no_sanitize("address"))) static void* 50+bind_thr(void* unused __attribute__((unused))) 51+{ 52+ while (!named_g_run_done) { 53+ usleep(300000); 54+ } 55+ 56+ int myfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 57+ if (myfd == -1) { 58+ perror("socket"); 59+ exit(1); 60+ } 61+ int val = 1; 62+ if (setsockopt(myfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) { 63+ perror("setsockopt(SO_REUSEADDR)"); 64+ } 65+ 66+ const struct sockaddr_in saddr = { 67+ .sin_family = AF_INET, 68+ .sin_port = htons(53), 69+ .sin_addr.s_addr = inet_addr("127.0.0.2"), 70+ }; 71+ if (bind(myfd, &saddr, sizeof(saddr)) == -1) { 72+ perror("bind"); 73+ exit(1); 74+ } 75+ 76+ if (listen(myfd, SOMAXCONN) == -1) { 77+ perror("listen"); 78+ exit(1); 79+ } 80+ 81+ for (;;) { 82+ struct sockaddr_in cli; 83+ socklen_t cli_len = sizeof(cli); 84+ 85+ int nfd = accept(myfd, &cli, &cli_len); 86+ if (nfd == -1) { 87+ perror("accept"); 88+ exit(1); 89+ } 90+ 91+ static char b[1024 * 1024]; 92+ ssize_t sz = recv(nfd, b, sizeof(b), 0); 93+ if (sz <= 0) { 94+ perror("recv"); 95+ _exit(1); 96+ } 97+ if (sz < 4) { 98+ close(nfd); 99+ continue; 100+ } 101+ if (rlen < 1) { 102+ close(nfd); 103+ continue; 104+ } 105+ 106+ /* It's a response, so set QR bit to 1 */ 107+ uint8_t qr = rbuf[0] | 0x80; 108+ 109+ uint16_t t_l = htons(rlen + 2); 110+ const struct iovec iov[] = { 111+ { 112+ .iov_base = &t_l, 113+ .iov_len = sizeof(t_l), 114+ }, 115+ { 116+ .iov_base = &b[2], 117+ .iov_len = 2, 118+ }, 119+ { 120+ .iov_base = &qr, 121+ .iov_len = 1, 122+ }, 123+ { 124+ .iov_base = (void*)&rbuf[1], 125+ .iov_len = rlen - 1, 126+ }, 127+ }; 128+ 129+ if (writev(nfd, iov, 4) == -1) { 130+ perror("writev() failed"); 131+ } 132+ 133+ close(nfd); 134+ } 135+ 136+ return NULL; 137+} 138+ 139+static void rndloop(int sock) 140+{ 141+ const struct sockaddr_in bsaddr = { 142+ .sin_family = AF_INET, 143+ .sin_port = htons(0), 144+ .sin_addr.s_addr = htonl((((uint32_t)util_rnd64()) & 0x00FFFFFF) | 0x7F000000), 145+ }; 146+ if (bind(sock, (const struct sockaddr*)&bsaddr, sizeof(bsaddr)) == -1) { 147+ perror("bind"); 148+ } 149+} 150+ 151+__attribute__((no_sanitize("memory"))) 152+__attribute__((no_sanitize("address"))) static void* 153+connect_thr(void* unused __attribute__((unused))) 154+{ 155+ while (!named_g_run_done) { 156+ usleep(300000); 157+ } 158+ 159+ for (;;) { 160+ int myfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 161+ if (myfd == -1) { 162+ perror("socket"); 163+ exit(1); 164+ } 165+ int val = 1; 166+ if (setsockopt(myfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) { 167+ perror("setsockopt(SO_REUSEADDR)"); 168+ } 169+ 170+ rndloop(myfd); 171+ 172+ const struct sockaddr_in saddr = { 173+ .sin_family = AF_INET, 174+ .sin_port = htons(53), 175+ .sin_addr.s_addr = htonl(INADDR_LOOPBACK), 176+ }; 177+ if (connect(myfd, &saddr, sizeof(saddr)) == -1) { 178+ close(myfd); 179+ continue; 180+ } 181+ 182+ const uint8_t* buf; 183+ size_t len; 184+ 185+ if (named_g_fuzz_type == isc_fuzz_client) { 186+ HF_ITER(&buf, &len); 187+ 188+ rlen = 0; 189+ rbuf = NULL; 190+ 191+ if (len < 32) { 192+ close(myfd); 193+ continue; 194+ } 195+ 196+ uint32_t tmplen = *((const uint32_t*)buf); 197+ 198+ buf = &buf[sizeof(uint32_t)]; 199+ len -= sizeof(uint32_t); 200+ 201+ tmplen %= len; 202+ 203+ rbuf = &buf[tmplen]; 204+ rlen = len - tmplen; 205+ len = tmplen; 206+ } else { 207+ static const uint8_t qbuf[] = { 208+ 0x88, 0x0c, 0x01, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 209+ 0x00, 0x01, 0x0a, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 210+ 0x61, 0x61, 0x61, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 211+ 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10, 212+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 213+ }; 214+ buf = qbuf; 215+ len = sizeof(qbuf); 216+ HF_ITER(&rbuf, &rlen); 217+ } 218+ 219+ uint16_t t_l = htons(len); 220+ const struct iovec iov[] = { 221+ { 222+ .iov_base = &t_l, 223+ .iov_len = sizeof(t_l), 224+ }, 225+ { 226+ .iov_base = (void*)buf, 227+ .iov_len = len, 228+ }, 229+ }; 230+ 231+ if (writev(myfd, iov, 2) == -1) { 232+ perror("write"); 233+ close(myfd); 234+ continue; 235+ } 236+ 237+ if (shutdown(myfd, SHUT_WR) == -1) { 238+ if (errno == ENOTCONN) { 239+ close(myfd); 240+ continue; 241+ } 242+ perror("shutdown"); 243+ _exit(1); 244+ } 245+ 246+ uint8_t b[1024 * 512]; 247+ while (recv(myfd, b, sizeof(b), 0) > 0) 248+ ; 249+ close(myfd); 250+ } 251+} 252+ 253+static void launch_thr(void) 254+{ 255+ pthread_attr_t attr; 256+ pthread_attr_init(&attr); 257+ pthread_attr_setstacksize(&attr, 1024 * 1024 * 4); 258+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 259+ 260+ pthread_t t; 261+ if (pthread_create(&t, &attr, bind_thr, NULL) < 0) { 262+ perror("pthread_create(bind_thr)"); 263+ exit(1); 264+ } 265+ 266+ pthread_attr_init(&attr); 267+ pthread_attr_setstacksize(&attr, 1024 * 1024 * 4); 268+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 269+ if (pthread_create(&t, &attr, connect_thr, NULL) < 0) { 270+ perror("pthread_create(connect_thr)"); 271+ exit(1); 272+ } 273+} 274+ 275 /* main entry point, possibly hooked */ 276 277-int 278-main(int argc, char *argv[]) { 279- isc_result_t result; 280+int main(int argc, char* argv[]) 281+{ 282+ if (!getenv("NO_FUZZ")) { 283+ named_g_fuzz_addr = "127.0.0.1:53"; 284+ named_g_fuzz_type = isc_fuzz_client; 285+ enter_namespaces(); 286+ launch_thr(); 287+ } 288+ 289+ isc_result_t result; 290 #ifdef HAVE_LIBSCF 291 char *instance = NULL; 292 #endif 293diff -Nur ORIG.bind-9.13.5-W1/compile.sh bind-9.13.5-W1/compile.sh 294--- ORIG.bind-9.13.5-W1/compile.sh 1970-01-01 01:00:00.000000000 +0100 295+++ bind-9.13.5-W1/compile.sh 2019-01-11 17:37:23.537289679 +0100 296@@ -0,0 +1,26 @@ 297+#!/bin/sh 298+ 299+set -ex 300+ 301+export CC=/home/jagger/src/honggfuzz/hfuzz_cc/hfuzz-clang 302+export CXX=/home/jagger/src/honggfuzz/hfuzz_cc/hfuzz-clang++ 303+export CFLAGS="-fsanitize=address -Wno-shift-negative-value -Wno-logical-not-parentheses -g -ggdb -O3 -march=native -D__AFL_COMPILER" 304+export LDFLAGS="-fno-sanitize=fuzzer" 305+./configure \ 306+ --prefix=/home/jagger/fuzz/bind/dist/ \ 307+ --enable-threads \ 308+ --without-gssapi \ 309+ --disable-chroot \ 310+ --disable-linux-caps \ 311+ --enable-seccomp \ 312+ --without-libtool \ 313+ --enable-ipv6 \ 314+ --enable-atomic \ 315+ --enable-epoll \ 316+ --enable-fuzzing=afl \ 317+ --disable-crypto-rand \ 318+ --disable-backtrace \ 319+ --with-openssl=yes 320+ 321+make clean 322+make -j$(nproc) 323diff -Nur ORIG.bind-9.13.5-W1/lib/dns/request.c bind-9.13.5-W1/lib/dns/request.c 324--- ORIG.bind-9.13.5-W1/lib/dns/request.c 2018-12-17 23:27:19.000000000 +0100 325+++ bind-9.13.5-W1/lib/dns/request.c 2019-01-11 17:37:23.537289679 +0100 326@@ -760,7 +760,7 @@ 327 goto cleanup; 328 } 329 330- if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512) 331+ if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length >= 0) 332 tcp = true; 333 share = (options & DNS_REQUESTOPT_SHARE); 334 335@@ -1050,6 +1050,8 @@ 336 dns_compress_t cctx; 337 bool cleanup_cctx = false; 338 339+ options |= DNS_REQUESTOPT_TCP; 340+ 341 REQUIRE(bufferp != NULL && *bufferp == NULL); 342 343 req_log(ISC_LOG_DEBUG(3), "request_render"); 344diff -Nur ORIG.bind-9.13.5-W1/lib/dns/resolver.c bind-9.13.5-W1/lib/dns/resolver.c 345--- ORIG.bind-9.13.5-W1/lib/dns/resolver.c 2018-12-17 23:27:19.000000000 +0100 346+++ bind-9.13.5-W1/lib/dns/resolver.c 2019-01-11 17:37:23.537289679 +0100 347@@ -1928,7 +1928,7 @@ 348 goto stop_idle_timer; 349 } 350 query->mctx = fctx->mctx; 351- query->options = options; 352+ query->options = options | DNS_FETCHOPT_TCP; 353 query->attributes = 0; 354 query->sends = 0; 355 query->connects = 0; 356diff -Nur ORIG.bind-9.13.5-W1/lib/isc/random.c bind-9.13.5-W1/lib/isc/random.c 357--- ORIG.bind-9.13.5-W1/lib/isc/random.c 2018-12-17 23:27:19.000000000 +0100 358+++ bind-9.13.5-W1/lib/isc/random.c 2019-01-11 17:38:09.005946234 +0100 359@@ -96,6 +96,7 @@ 360 isc_random8(void) { 361 RUNTIME_CHECK(isc_once_do(&isc_random_once, 362 isc_random_initialize) == ISC_R_SUCCESS); 363+ return 1; 364 return (next() & 0xff); 365 } 366 367@@ -103,6 +104,7 @@ 368 isc_random16(void) { 369 RUNTIME_CHECK(isc_once_do(&isc_random_once, 370 isc_random_initialize) == ISC_R_SUCCESS); 371+ return 1; 372 return (next() & 0xffff); 373 } 374 375@@ -110,6 +112,7 @@ 376 isc_random32(void) { 377 RUNTIME_CHECK(isc_once_do(&isc_random_once, 378 isc_random_initialize) == ISC_R_SUCCESS); 379+ return 1; 380 return (next()); 381 } 382 383@@ -124,6 +127,13 @@ 384 RUNTIME_CHECK(isc_once_do(&isc_random_once, 385 isc_random_initialize) == ISC_R_SUCCESS); 386 387+ for (size_t z = 0; z < buflen; z++) { 388+ char * b = (char*)buf; 389+ b[z] = z + 1; 390+ } 391+ return; 392+ 393+ 394 for (i = 0; i + sizeof(r) <= buflen; i += sizeof(r)) { 395 r = next(); 396 memmove((uint8_t *)buf + i, &r, sizeof(r)); 397