1 diff -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 } 50 diff -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 */ 340 diff -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 } 352 diff -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) 381 diff -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 } 413 diff -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; 424 diff -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