391 lines
10 KiB
Diff
391 lines
10 KiB
Diff
diff -Nur ORIG.bind-9.14.1/bin/named/main.c bind-9.14.1/bin/named/main.c
|
|
--- ORIG.bind-9.14.1/bin/named/main.c 2019-04-06 22:09:59.000000000 +0200
|
|
+++ bind-9.14.1/bin/named/main.c 2019-05-09 16:26:27.615239219 +0200
|
|
@@ -1347,11 +1347,285 @@
|
|
}
|
|
#endif /* HAVE_LIBSCF */
|
|
|
|
+#include <named/globals.h>
|
|
+
|
|
+#include <arpa/inet.h>
|
|
+#include <errno.h>
|
|
+#include <fcntl.h>
|
|
+#include <net/if.h>
|
|
+#include <net/route.h>
|
|
+#include <netinet/ip6.h>
|
|
+#include <netinet/tcp.h>
|
|
+#include <pthread.h>
|
|
+#include <sched.h>
|
|
+#include <sys/ioctl.h>
|
|
+#include <sys/resource.h>
|
|
+#include <sys/socket.h>
|
|
+#include <sys/stat.h>
|
|
+#include <sys/time.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/uio.h>
|
|
+#include <sys/wait.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#include <libhfcommon/util.h>
|
|
+#include <libhfuzz/libhfuzz.h>
|
|
+
|
|
+static void enter_namespaces(void)
|
|
+{
|
|
+ if (linuxEnterNs(CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWIPC) == false) {
|
|
+ exit(1);
|
|
+ }
|
|
+ if (linuxIfaceUp("lo") == false) {
|
|
+ exit(1);
|
|
+ }
|
|
+ if (linuxMountTmpfs("/tmp") == false) {
|
|
+ exit(1);
|
|
+ }
|
|
+}
|
|
+
|
|
+static size_t rlen = 0;
|
|
+static const uint8_t* rbuf = NULL;
|
|
+
|
|
+__attribute__((no_sanitize("memory")))
|
|
+__attribute__((no_sanitize("address"))) static void*
|
|
+bind_thr(void* unused __attribute__((unused)))
|
|
+{
|
|
+ while (!named_g_run_done) {
|
|
+ usleep(300000);
|
|
+ }
|
|
+
|
|
+ int myfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
|
+ if (myfd == -1) {
|
|
+ perror("socket");
|
|
+ exit(1);
|
|
+ }
|
|
+ int val = 1;
|
|
+ if (setsockopt(myfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) {
|
|
+ perror("setsockopt(SO_REUSEADDR)");
|
|
+ }
|
|
+
|
|
+ const struct sockaddr_in saddr = {
|
|
+ .sin_family = AF_INET,
|
|
+ .sin_port = htons(53),
|
|
+ .sin_addr.s_addr = inet_addr("127.0.0.2"),
|
|
+ };
|
|
+ if (bind(myfd, &saddr, sizeof(saddr)) == -1) {
|
|
+ perror("bind");
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ if (listen(myfd, SOMAXCONN) == -1) {
|
|
+ perror("listen");
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ for (;;) {
|
|
+ struct sockaddr_in cli;
|
|
+ socklen_t cli_len = sizeof(cli);
|
|
+
|
|
+ int nfd = accept(myfd, &cli, &cli_len);
|
|
+ if (nfd == -1) {
|
|
+ perror("accept");
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ static char b[1024 * 1024];
|
|
+ ssize_t sz = recv(nfd, b, sizeof(b), 0);
|
|
+ if (sz <= 0) {
|
|
+ perror("recv");
|
|
+ _exit(1);
|
|
+ }
|
|
+ if (sz < 4) {
|
|
+ close(nfd);
|
|
+ continue;
|
|
+ }
|
|
+ if (rlen < 1) {
|
|
+ close(nfd);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /* It's a response, so set QR bit to 1 */
|
|
+ uint8_t qr = rbuf[0] | 0x80;
|
|
+
|
|
+ uint16_t t_l = htons(rlen + 2);
|
|
+ const struct iovec iov[] = {
|
|
+ {
|
|
+ .iov_base = &t_l,
|
|
+ .iov_len = sizeof(t_l),
|
|
+ },
|
|
+ {
|
|
+ .iov_base = &b[2],
|
|
+ .iov_len = 2,
|
|
+ },
|
|
+ {
|
|
+ .iov_base = &qr,
|
|
+ .iov_len = 1,
|
|
+ },
|
|
+ {
|
|
+ .iov_base = (void*)&rbuf[1],
|
|
+ .iov_len = rlen - 1,
|
|
+ },
|
|
+ };
|
|
+
|
|
+ if (writev(nfd, iov, 4) == -1) {
|
|
+ perror("writev() failed");
|
|
+ }
|
|
+
|
|
+ close(nfd);
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static void rndloop(int sock)
|
|
+{
|
|
+ const struct sockaddr_in bsaddr = {
|
|
+ .sin_family = AF_INET,
|
|
+ .sin_port = htons(0),
|
|
+ .sin_addr.s_addr = htonl((((uint32_t)util_rnd64()) & 0x00FFFFFF) | 0x7F000000),
|
|
+ };
|
|
+ if (bind(sock, (const struct sockaddr*)&bsaddr, sizeof(bsaddr)) == -1) {
|
|
+ perror("bind");
|
|
+ }
|
|
+}
|
|
+
|
|
+__attribute__((no_sanitize("memory")))
|
|
+__attribute__((no_sanitize("address"))) static void*
|
|
+connect_thr(void* unused __attribute__((unused)))
|
|
+{
|
|
+ while (!named_g_run_done) {
|
|
+ usleep(300000);
|
|
+ }
|
|
+
|
|
+ for (;;) {
|
|
+ int myfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
|
+ if (myfd == -1) {
|
|
+ perror("socket");
|
|
+ exit(1);
|
|
+ }
|
|
+ int val = 1;
|
|
+ if (setsockopt(myfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) {
|
|
+ perror("setsockopt(SO_REUSEADDR)");
|
|
+ }
|
|
+
|
|
+ rndloop(myfd);
|
|
+
|
|
+ const struct sockaddr_in saddr = {
|
|
+ .sin_family = AF_INET,
|
|
+ .sin_port = htons(53),
|
|
+ .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
|
|
+ };
|
|
+ if (connect(myfd, &saddr, sizeof(saddr)) == -1) {
|
|
+ close(myfd);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ const uint8_t* buf;
|
|
+ size_t len;
|
|
+
|
|
+ if (named_g_fuzz_type == isc_fuzz_client) {
|
|
+ HF_ITER(&buf, &len);
|
|
+
|
|
+ rlen = 0;
|
|
+ rbuf = NULL;
|
|
+
|
|
+ if (len < 32) {
|
|
+ close(myfd);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ uint32_t tmplen = *((const uint32_t*)buf);
|
|
+
|
|
+ buf = &buf[sizeof(uint32_t)];
|
|
+ len -= sizeof(uint32_t);
|
|
+
|
|
+ tmplen %= len;
|
|
+
|
|
+ rbuf = &buf[tmplen];
|
|
+ rlen = len - tmplen;
|
|
+ len = tmplen;
|
|
+ } else {
|
|
+ static const uint8_t qbuf[] = {
|
|
+ 0x88, 0x0c, 0x01, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x01, 0x0a, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
|
|
+ 0x61, 0x61, 0x61, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
|
|
+ 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10,
|
|
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00
|
|
+ };
|
|
+ buf = qbuf;
|
|
+ len = sizeof(qbuf);
|
|
+ HF_ITER(&rbuf, &rlen);
|
|
+ }
|
|
+
|
|
+ uint16_t t_l = htons(len);
|
|
+ const struct iovec iov[] = {
|
|
+ {
|
|
+ .iov_base = &t_l,
|
|
+ .iov_len = sizeof(t_l),
|
|
+ },
|
|
+ {
|
|
+ .iov_base = (void*)buf,
|
|
+ .iov_len = len,
|
|
+ },
|
|
+ };
|
|
+
|
|
+ if (writev(myfd, iov, 2) == -1) {
|
|
+ perror("write");
|
|
+ close(myfd);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (shutdown(myfd, SHUT_WR) == -1) {
|
|
+ if (errno == ENOTCONN) {
|
|
+ close(myfd);
|
|
+ continue;
|
|
+ }
|
|
+ perror("shutdown");
|
|
+ _exit(1);
|
|
+ }
|
|
+
|
|
+ uint8_t b[1024 * 512];
|
|
+ while (recv(myfd, b, sizeof(b), 0) > 0)
|
|
+ ;
|
|
+ close(myfd);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void launch_thr(void)
|
|
+{
|
|
+ pthread_attr_t attr;
|
|
+ pthread_attr_init(&attr);
|
|
+ pthread_attr_setstacksize(&attr, 1024 * 1024 * 4);
|
|
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
+
|
|
+ pthread_t t;
|
|
+ if (pthread_create(&t, &attr, bind_thr, NULL) < 0) {
|
|
+ perror("pthread_create(bind_thr)");
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ pthread_attr_init(&attr);
|
|
+ pthread_attr_setstacksize(&attr, 1024 * 1024 * 4);
|
|
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
+ if (pthread_create(&t, &attr, connect_thr, NULL) < 0) {
|
|
+ perror("pthread_create(connect_thr)");
|
|
+ exit(1);
|
|
+ }
|
|
+}
|
|
+
|
|
/* main entry point, possibly hooked */
|
|
|
|
-int
|
|
-main(int argc, char *argv[]) {
|
|
- isc_result_t result;
|
|
+int main(int argc, char* argv[])
|
|
+{
|
|
+ if (!getenv("NO_FUZZ")) {
|
|
+ named_g_fuzz_addr = "127.0.0.1:53";
|
|
+ named_g_fuzz_type = isc_fuzz_client;
|
|
+ enter_namespaces();
|
|
+ launch_thr();
|
|
+ }
|
|
+
|
|
+ isc_result_t result;
|
|
#ifdef HAVE_LIBSCF
|
|
char *instance = NULL;
|
|
#endif
|
|
diff -Nur ORIG.bind-9.14.1/compile.sh bind-9.14.1/compile.sh
|
|
--- ORIG.bind-9.14.1/compile.sh 1970-01-01 01:00:00.000000000 +0100
|
|
+++ bind-9.14.1/compile.sh 2019-05-09 16:27:15.139211816 +0200
|
|
@@ -0,0 +1,20 @@
|
|
+#!/bin/sh
|
|
+
|
|
+set -ex
|
|
+
|
|
+export CC="$HOME"/src/honggfuzz/hfuzz_cc/hfuzz-clang
|
|
+export CXX="$HOME"/src/honggfuzz/hfuzz_cc/hfuzz-clang++
|
|
+export CFLAGS="-fsanitize=address -Wno-shift-negative-value -Wno-logical-not-parentheses -g -ggdb -O0 -D__AFL_COMPILER"
|
|
+./configure \
|
|
+ --prefix="$HOME"/fuzz/bind/dist/ \
|
|
+ --without-gssapi \
|
|
+ --disable-chroot \
|
|
+ --disable-linux-caps \
|
|
+ --without-libtool \
|
|
+ --enable-epoll \
|
|
+ --enable-fuzzing=afl \
|
|
+ --disable-backtrace \
|
|
+ --with-openssl=yes
|
|
+
|
|
+make clean
|
|
+make -j$(nproc)
|
|
diff -Nur ORIG.bind-9.14.1/lib/dns/request.c bind-9.14.1/lib/dns/request.c
|
|
--- ORIG.bind-9.14.1/lib/dns/request.c 2019-04-06 22:09:59.000000000 +0200
|
|
+++ bind-9.14.1/lib/dns/request.c 2019-05-09 16:26:27.615239219 +0200
|
|
@@ -760,7 +760,7 @@
|
|
goto cleanup;
|
|
}
|
|
|
|
- if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512)
|
|
+ if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length >= 0)
|
|
tcp = true;
|
|
share = (options & DNS_REQUESTOPT_SHARE);
|
|
|
|
@@ -1050,6 +1050,8 @@
|
|
dns_compress_t cctx;
|
|
bool cleanup_cctx = false;
|
|
|
|
+ options |= DNS_REQUESTOPT_TCP;
|
|
+
|
|
REQUIRE(bufferp != NULL && *bufferp == NULL);
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "request_render");
|
|
diff -Nur ORIG.bind-9.14.1/lib/dns/resolver.c bind-9.14.1/lib/dns/resolver.c
|
|
--- ORIG.bind-9.14.1/lib/dns/resolver.c 2019-04-06 22:09:59.000000000 +0200
|
|
+++ bind-9.14.1/lib/dns/resolver.c 2019-05-09 16:26:27.619239217 +0200
|
|
@@ -1951,7 +1951,7 @@
|
|
goto stop_idle_timer;
|
|
}
|
|
query->mctx = fctx->mctx;
|
|
- query->options = options;
|
|
+ query->options = options | DNS_FETCHOPT_TCP;
|
|
query->attributes = 0;
|
|
query->sends = 0;
|
|
query->connects = 0;
|
|
diff -Nur ORIG.bind-9.14.1/lib/isc/random.c bind-9.14.1/lib/isc/random.c
|
|
--- ORIG.bind-9.14.1/lib/isc/random.c 2019-04-06 22:09:59.000000000 +0200
|
|
+++ bind-9.14.1/lib/isc/random.c 2019-05-09 16:26:27.619239217 +0200
|
|
@@ -96,6 +96,7 @@
|
|
isc_random8(void) {
|
|
RUNTIME_CHECK(isc_once_do(&isc_random_once,
|
|
isc_random_initialize) == ISC_R_SUCCESS);
|
|
+ return 1;
|
|
return (next() & 0xff);
|
|
}
|
|
|
|
@@ -103,6 +104,7 @@
|
|
isc_random16(void) {
|
|
RUNTIME_CHECK(isc_once_do(&isc_random_once,
|
|
isc_random_initialize) == ISC_R_SUCCESS);
|
|
+ return 1;
|
|
return (next() & 0xffff);
|
|
}
|
|
|
|
@@ -110,6 +112,7 @@
|
|
isc_random32(void) {
|
|
RUNTIME_CHECK(isc_once_do(&isc_random_once,
|
|
isc_random_initialize) == ISC_R_SUCCESS);
|
|
+ return 1;
|
|
return (next());
|
|
}
|
|
|
|
@@ -124,6 +127,13 @@
|
|
RUNTIME_CHECK(isc_once_do(&isc_random_once,
|
|
isc_random_initialize) == ISC_R_SUCCESS);
|
|
|
|
+ for (size_t z = 0; z < buflen; z++) {
|
|
+ char * b = (char*)buf;
|
|
+ b[z] = z + 1;
|
|
+ }
|
|
+ return;
|
|
+
|
|
+
|
|
for (i = 0; i + sizeof(r) <= buflen; i += sizeof(r)) {
|
|
r = next();
|
|
memmove((uint8_t *)buf + i, &r, sizeof(r));
|