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