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