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