• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff -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 }
50diff -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 	 */
340diff -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 }
352diff -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)
381diff -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 	}
413diff -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;
424diff -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