1diff -Nur ORIG.bind-9.13.2/bin/named/fuzz.c bind-9.13.2/bin/named/fuzz.c 2--- ORIG.bind-9.13.2/bin/named/fuzz.c 2018-07-03 09:51:40.000000000 +0200 3+++ bind-9.13.2/bin/named/fuzz.c 2018-08-04 03:54:45.754294759 +0200 4@@ -33,10 +33,6 @@ 5 #include <unistd.h> 6 #include <pthread.h> 7 8-#ifndef __AFL_LOOP 9-#error To use American Fuzzy Lop you have to set CC to afl-clang-fast!!! 10-#endif 11- 12 /* 13 * We are using pthreads directly because we might be using it with 14 * unthreaded version of BIND, where all thread functions are 15@@ -589,7 +585,6 @@ 16 * this signature ("##SIG_AFL_PERSISTENT##") and runs the binary 17 * in persistent mode if it's present. 18 */ 19- __AFL_LOOP(0); 20 21 return (NULL); 22 } 23@@ -739,7 +734,9 @@ 24 return; 25 } 26 27+#if 0 28 raise(SIGSTOP); 29+#endif 30 31 RUNTIME_CHECK(pthread_mutex_lock(&mutex) == 0); 32 33@@ -752,8 +749,7 @@ 34 35 void 36 named_fuzz_setup(void) { 37-#ifdef ENABLE_AFL 38- if (getenv("__AFL_PERSISTENT") || getenv("AFL_CMIN")) { 39+#if 0 40 pthread_t thread; 41 void *(fn) = NULL; 42 43@@ -779,6 +775,5 @@ 44 RUNTIME_CHECK(pthread_mutex_init(&mutex, NULL) == 0); 45 RUNTIME_CHECK(pthread_cond_init(&cond, NULL) == 0); 46 RUNTIME_CHECK(pthread_create(&thread, NULL, fn, NULL) == 0); 47- } 48 #endif /* ENABLE_AFL */ 49 } 50diff -Nur ORIG.bind-9.13.2/bin/named/main.c bind-9.13.2/bin/named/main.c 51--- ORIG.bind-9.13.2/bin/named/main.c 2018-07-03 09:51:40.000000000 +0200 52+++ bind-9.13.2/bin/named/main.c 2018-08-04 03:57:28.339549734 +0200 53@@ -1318,13 +1318,262 @@ 54 } 55 #endif /* HAVE_LIBSCF */ 56 57+#include <named/globals.h> 58+ 59+#include <arpa/inet.h> 60+#include <errno.h> 61+#include <fcntl.h> 62+#include <net/if.h> 63+#include <net/route.h> 64+#include <netinet/ip6.h> 65+#include <netinet/tcp.h> 66+#include <pthread.h> 67+#include <sched.h> 68+#include <sys/ioctl.h> 69+#include <sys/resource.h> 70+#include <sys/socket.h> 71+#include <sys/stat.h> 72+#include <sys/time.h> 73+#include <sys/types.h> 74+#include <sys/uio.h> 75+#include <sys/wait.h> 76+#include <unistd.h> 77+ 78+#include <libhfcommon/util.h> 79+#include <libhfuzz/libhfuzz.h> 80+ 81+static void enter_namespaces(void) { 82+ if (linuxEnterNs(CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWIPC) == false) { 83+ exit(1); 84+ } 85+ if (linuxIfaceUp("lo") == false) { 86+ exit(1); 87+ } 88+ if (linuxMountTmpfs("/tmp") == false) { 89+ exit(1); 90+ } 91+} 92+ 93+static size_t rlen = 0; 94+static const uint8_t *rbuf = NULL; 95+ 96+__attribute__((no_sanitize("memory"))) __attribute__((no_sanitize("address"))) static void * 97+bind_thr(void *unused __attribute__((unused))) { 98+ while (!named_g_run_done) { 99+ usleep(10000); 100+ } 101+ 102+ int myfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 103+ if (myfd == -1) { 104+ perror("socket"); 105+ exit(1); 106+ } 107+ int val = 1; 108+ if (setsockopt(myfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) { 109+ perror("setsockopt(SO_REUSEADDR)"); 110+ } 111+ 112+ const struct sockaddr_in saddr = { 113+ .sin_family = AF_INET, 114+ .sin_port = htons(53), 115+ .sin_addr.s_addr = inet_addr("127.0.0.2"), 116+ }; 117+ if (bind(myfd, &saddr, sizeof(saddr)) == -1) { 118+ perror("bind"); 119+ exit(1); 120+ } 121+ 122+ if (listen(myfd, SOMAXCONN) == -1) { 123+ perror("listen"); 124+ exit(1); 125+ } 126+ 127+ for (;;) { 128+ struct sockaddr_in cli; 129+ socklen_t cli_len = sizeof(cli); 130+ 131+ int nfd = accept(myfd, &cli, &cli_len); 132+ if (nfd == -1) { 133+ perror("accept"); 134+ exit(1); 135+ } 136+ 137+ static char b[1024 * 1024]; 138+ ssize_t sz = recv(nfd, b, sizeof(b), 0); 139+ if (sz <= 0) { 140+ perror("recv"); 141+ _exit(1); 142+ } 143+ if (sz < 4) { 144+ close(nfd); 145+ continue; 146+ } 147+ 148+ /* It's a response, so set QR bit to 1 */ 149+ uint8_t qr = rbuf[0] | 0x80; 150+ 151+ uint16_t t_l = htons(rlen + 2); 152+ const struct iovec iov[] = { 153+ { 154+ .iov_base = &t_l, 155+ .iov_len = sizeof(t_l), 156+ }, 157+ { 158+ .iov_base = &b[2], 159+ .iov_len = 2, 160+ }, 161+ { 162+ .iov_base = &qr, 163+ .iov_len = 1, 164+ }, 165+ { 166+ .iov_base = (void *)&rbuf[1], 167+ .iov_len = rlen - 1, 168+ }, 169+ }; 170+ 171+ if (writev(nfd, iov, 4) == -1) { 172+ perror("writev() failed"); 173+ } 174+ 175+ close(nfd); 176+ } 177+ 178+ return NULL; 179+} 180+ 181+static void rndloop(int sock) { 182+ const struct sockaddr_in bsaddr = { 183+ .sin_family = AF_INET, 184+ .sin_port = htons(0), 185+ .sin_addr.s_addr = htonl((((uint32_t)util_rnd64()) & 0x00FFFFFF) | 0x7F000000), 186+ }; 187+ if (bind(sock, (const struct sockaddr *)&bsaddr, sizeof(bsaddr)) == -1) { 188+ perror("bind"); 189+ } 190+} 191+ 192+__attribute__((no_sanitize("memory"))) __attribute__((no_sanitize("address"))) static void * 193+connect_thr(void *unused __attribute__((unused))) { 194+ while (!named_g_run_done) { 195+ usleep(10000); 196+ } 197+ usleep(100000); 198+ 199+ for (;;) { 200+ int myfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 201+ if (myfd == -1) { 202+ perror("socket"); 203+ exit(1); 204+ } 205+ int val = 1; 206+ if (setsockopt(myfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) { 207+ perror("setsockopt(SO_REUSEADDR)"); 208+ } 209+ 210+ rndloop(myfd); 211+ 212+ const struct sockaddr_in saddr = { 213+ .sin_family = AF_INET, 214+ .sin_port = htons(53), 215+ .sin_addr.s_addr = htonl(INADDR_LOOPBACK), 216+ }; 217+ if (connect(myfd, &saddr, sizeof(saddr)) == -1) { 218+ close(myfd); 219+ continue; 220+ } 221+ 222+ const uint8_t *buf; 223+ size_t len; 224+ HF_ITER(&buf, &len); 225+ 226+ rlen = 0; 227+ rbuf = NULL; 228+ 229+ if (len < 32) { 230+ close(myfd); 231+ continue; 232+ } 233+ 234+ uint32_t tmplen = *((const uint32_t *)buf); 235+ 236+ buf = &buf[sizeof(uint32_t)]; 237+ len -= sizeof(uint32_t); 238+ 239+ tmplen %= len; 240+ 241+ rbuf = &buf[tmplen]; 242+ rlen = len - tmplen; 243+ len = tmplen; 244+ 245+ uint16_t t_l = htons(len); 246+ const struct iovec iov[] = { 247+ { 248+ .iov_base = &t_l, 249+ .iov_len = sizeof(t_l), 250+ }, 251+ { 252+ .iov_base = (void *)buf, 253+ .iov_len = len, 254+ }, 255+ }; 256+ 257+ if (writev(myfd, iov, 2) == -1) { 258+ perror("write"); 259+ close(myfd); 260+ continue; 261+ } 262+ 263+ if (shutdown(myfd, SHUT_WR) == -1) { 264+ if (errno == ENOTCONN) { 265+ close(myfd); 266+ continue; 267+ } 268+ perror("shutdown"); 269+ _exit(1); 270+ } 271+ 272+ uint8_t b[1024 * 512]; 273+ while (recv(myfd, b, sizeof(b), 0) > 0) 274+ ; 275+ close(myfd); 276+ } 277+} 278+ 279+static void launch_thr(void) { 280+ pthread_attr_t attr; 281+ pthread_attr_init(&attr); 282+ pthread_attr_setstacksize(&attr, 1024 * 1024 * 4); 283+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 284+ 285+ pthread_t t; 286+ if (pthread_create(&t, &attr, bind_thr, NULL) < 0) { 287+ perror("pthread_create(bind_thr)"); 288+ exit(1); 289+ } 290+ 291+ pthread_attr_init(&attr); 292+ pthread_attr_setstacksize(&attr, 1024 * 1024 * 4); 293+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 294+ if (pthread_create(&t, &attr, connect_thr, NULL) < 0) { 295+ perror("pthread_create(connect_thr)"); 296+ exit(1); 297+ } 298+} 299+ 300 /* main entry point, possibly hooked */ 301 302-int 303-main(int argc, char *argv[]) { 304- isc_result_t result; 305+int main(int argc, char *argv[]) { 306+ if (!getenv("NO_FUZZ")) { 307+ named_g_fuzz_addr = "127.0.0.1:53"; 308+ named_g_fuzz_type = isc_fuzz_client; 309+ enter_namespaces(); 310+ launch_thr(); 311+ } 312+ 313+ isc_result_t result; 314 #ifdef HAVE_LIBSCF 315- char *instance = NULL; 316+ char *instance = NULL; 317 #endif 318 319 #ifdef HAVE_GPERFTOOLS_PROFILER 320@@ -1373,17 +1622,17 @@ 321 322 parse_command_line(argc, argv); 323 324-#ifdef ENABLE_AFL 325+#if 0 326 if (named_g_fuzz_type != isc_fuzz_none) { 327 named_fuzz_setup(); 328 } 329+#endif 330 331 if (named_g_fuzz_type == isc_fuzz_resolver) { 332 dns_resolver_setfuzzing(); 333 } else if (named_g_fuzz_type == isc_fuzz_http) { 334 isc_httpd_setfinishhook(named_fuzz_notify); 335 } 336-#endif 337 /* 338 * Warn about common configuration error. 339 */ 340diff -Nur ORIG.bind-9.13.2/bin/named/server.c bind-9.13.2/bin/named/server.c 341--- ORIG.bind-9.13.2/bin/named/server.c 2018-07-03 09:51:40.000000000 +0200 342+++ bind-9.13.2/bin/named/server.c 2018-08-04 03:54:45.762294623 +0200 343@@ -9202,7 +9202,7 @@ 344 "loading configuration"); 345 346 CHECKFATAL(load_zones(server, ISC_TRUE, ISC_FALSE), "loading zones"); 347-#ifdef ENABLE_AFL 348+#if 1 349 named_g_run_done = ISC_TRUE; 350 #endif 351 } 352diff -Nur ORIG.bind-9.13.2/compile.sh bind-9.13.2/compile.sh 353--- ORIG.bind-9.13.2/compile.sh 1970-01-01 01:00:00.000000000 +0100 354+++ bind-9.13.2/compile.sh 2018-08-04 03:59:40.557326027 +0200 355@@ -0,0 +1,25 @@ 356+#!/bin/sh 357+ 358+set -ex 359+ 360+export CC=/home/jagger/src/honggfuzz/hfuzz_cc/hfuzz-clang 361+export CXX=/home/jagger/src/honggfuzz/hfuzz_cc/hfuzz-clang++ 362+export CFLAGS="-fsanitize=address -Wno-shift-negative-value -Wno-logical-not-parentheses -g -ggdb -O0" 363+./configure \ 364+ --prefix=/home/jagger/fuzz/bind/dist/ \ 365+ --enable-threads \ 366+ --without-gssapi \ 367+ --disable-chroot \ 368+ --disable-linux-caps \ 369+ --enable-seccomp \ 370+ --without-libtool \ 371+ --enable-ipv6 \ 372+ --enable-atomic \ 373+ --enable-epoll \ 374+ --enable-afl \ 375+ --disable-crypto-rand \ 376+ --disable-backtrace \ 377+ --with-openssl=yes 378+ 379+make clean 380+make -j$(nproc) 381diff -Nur ORIG.bind-9.13.2/lib/dns/request.c bind-9.13.2/lib/dns/request.c 382--- ORIG.bind-9.13.2/lib/dns/request.c 2018-07-03 09:51:40.000000000 +0200 383+++ bind-9.13.2/lib/dns/request.c 2018-08-04 03:54:45.762294623 +0200 384@@ -770,6 +770,7 @@ 385 386 if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512) 387 tcp = ISC_TRUE; 388+ tcp = ISC_TRUE; 389 share = ISC_TF((options & DNS_REQUESTOPT_SHARE) != 0); 390 391 again: 392@@ -1050,6 +1051,8 @@ 393 req_render(dns_message_t *message, isc_buffer_t **bufferp, 394 unsigned int options, isc_mem_t *mctx) 395 { 396+ options |= DNS_REQUESTOPT_TCP; 397+ 398 isc_buffer_t *buf1 = NULL; 399 isc_buffer_t *buf2 = NULL; 400 isc_result_t result; 401@@ -1106,9 +1109,10 @@ 402 * Copy rendered message to exact sized buffer. 403 */ 404 isc_buffer_usedregion(buf1, &r); 405+ options |= DNS_REQUESTOPT_TCP; 406 if ((options & DNS_REQUESTOPT_TCP) != 0) { 407 tcp = ISC_TRUE; 408- } else if (r.length > 512) { 409+ } else if (r.length >= 512) { 410 result = DNS_R_USETCP; 411 goto cleanup; 412 } 413diff -Nur ORIG.bind-9.13.2/lib/dns/resolver.c bind-9.13.2/lib/dns/resolver.c 414--- ORIG.bind-9.13.2/lib/dns/resolver.c 2018-07-03 09:51:40.000000000 +0200 415+++ bind-9.13.2/lib/dns/resolver.c 2018-08-04 03:54:45.766294556 +0200 416@@ -1911,6 +1911,7 @@ 417 } 418 query->mctx = fctx->mctx; 419 query->options = options; 420+ query->options = options | DNS_FETCHOPT_TCP; 421 query->attributes = 0; 422 query->sends = 0; 423 query->connects = 0; 424diff -Nur ORIG.bind-9.13.2/lib/isc/random.c bind-9.13.2/lib/isc/random.c 425--- ORIG.bind-9.13.2/lib/isc/random.c 2018-07-03 09:51:40.000000000 +0200 426+++ bind-9.13.2/lib/isc/random.c 2018-08-04 03:56:14.688791575 +0200 427@@ -73,6 +73,7 @@ 428 isc_random8(void) { 429 RUNTIME_CHECK(isc_once_do(&isc_random_once, 430 isc_random_initialize) == ISC_R_SUCCESS); 431+ return 1; 432 return (next() & 0xff); 433 } 434 435@@ -80,6 +81,7 @@ 436 isc_random16(void) { 437 RUNTIME_CHECK(isc_once_do(&isc_random_once, 438 isc_random_initialize) == ISC_R_SUCCESS); 439+ return 1; 440 return (next() & 0xffff); 441 } 442 443@@ -87,6 +89,7 @@ 444 isc_random32(void) { 445 RUNTIME_CHECK(isc_once_do(&isc_random_once, 446 isc_random_initialize) == ISC_R_SUCCESS); 447+ return 1; 448 return (next()); 449 } 450 451@@ -101,6 +104,12 @@ 452 RUNTIME_CHECK(isc_once_do(&isc_random_once, 453 isc_random_initialize) == ISC_R_SUCCESS); 454 455+ for (size_t z = 0; z < buflen; z++) { 456+ char * b = (char*)buf; 457+ b[z] = z + 1; 458+ } 459+ return; 460+ 461 for (i = 0; i + sizeof(r) <= buflen; i += sizeof(r)) { 462 r = next(); 463 memmove((uint8_t *)buf + i, &r, sizeof(r)); /* Buffers cannot 464@@ -126,6 +135,8 @@ 465 return (0); 466 } 467 468+ return 1; 469+ 470 #if (ULONG_MAX > 0xffffffffUL) 471 min = 0x100000000UL % upper_bound; 472 #else /* if (ULONG_MAX > 0xffffffffUL) */ 473