Home | History | Annotate | Download | only in bind
      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