• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git a/configure.ac b/configure.ac
2index 7975d31..528861c 100644
3--- a/configure.ac
4+++ b/configure.ac
5@@ -4399,6 +4399,37 @@ AC_DEFINE_UNQUOTED([DYNAMIC_INTERLEAVE], [$ntp_dynamic_interleave],
6     [support dynamic interleave?])
7 AC_MSG_RESULT([$ntp_ok])
8
9+AC_ARG_ENABLE(fuzztargets,
10+    AS_HELP_STRING([--enable-fuzztargets], [Enable fuzz targets]),[enable_fuzztargets=$enableval],[enable_fuzztargets=no])
11+AM_CONDITIONAL([BUILD_FUZZTARGETS], [test "x$enable_fuzztargets" = "xyes"])
12+AS_IF([test "x$enable_fuzztargets" = "xyes"], [
13+    AC_PROG_CXX
14+    AC_LANG_PUSH(C++)
15+    AS_IF([test "x$LIB_FUZZING_ENGINE" = "x"], [
16+        LIB_FUZZING_ENGINE=-fsanitize=fuzzer
17+        AC_SUBST(LIB_FUZZING_ENGINE)
18+    ])
19+    tmp_saved_flags=$[]_AC_LANG_PREFIX[]FLAGS
20+    _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $LIB_FUZZING_ENGINE"
21+    AC_MSG_CHECKING([whether $CXX accepts $LIB_FUZZING_ENGINE])
22+    AC_LINK_IFELSE([AC_LANG_SOURCE([[
23+#include <sys/types.h>
24+extern "C" int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size);
25+extern "C" int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size) {
26+(void)Data;
27+(void)Size;
28+return 0;
29+}
30+        ]])],
31+        [ AC_MSG_RESULT(yes)
32+          has_sanitizefuzzer=yes],
33+        [ AC_MSG_RESULT(no) ]
34+    )
35+    _AC_LANG_PREFIX[]FLAGS=$tmp_saved_flags, []
36+    AC_LANG_POP()
37+])
38+AM_CONDITIONAL([HAS_SANITIZEFUZZER], [test "x$has_sanitizefuzzer" = "xyes"])
39+
40 NTP_UNITYBUILD
41
42 dnl  gtest is needed for our tests subdirs. It would be nice if we could
43@@ -4459,6 +4490,7 @@ AC_CONFIG_FILES([tests/ntpd/Makefile])
44 AC_CONFIG_FILES([tests/ntpq/Makefile])
45 AC_CONFIG_FILES([tests/sandbox/Makefile])
46 AC_CONFIG_FILES([tests/sec-2853/Makefile])
47+AC_CONFIG_FILES([tests/fuzz/Makefile])
48 AC_CONFIG_FILES([util/Makefile])
49
50 perllibdir="${datadir}/ntp/lib"
51diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c
52index 7c3fdd4..190a373 100644
53--- a/ntpd/ntp_io.c
54+++ b/ntpd/ntp_io.c
55@@ -503,7 +503,11 @@ io_open_sockets(void)
56 	 * Create the sockets
57 	 */
58 	BLOCKIO();
59+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
60+	create_sockets(4123);
61+#else
62 	create_sockets(NTP_PORT);
63+#endif
64 	UNBLOCKIO();
65
66 	init_async_notifications();
67diff --git a/tests/Makefile.am b/tests/Makefile.am
68index af502b9..60a2379 100644
69--- a/tests/Makefile.am
70+++ b/tests/Makefile.am
71@@ -10,3 +10,6 @@ SUBDIRS +=		\
72 	sec-2853	\
73 	$(NULL)
74
75+if BUILD_FUZZTARGETS
76+    SUBDIRS += fuzz
77+endif
78diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am
79new file mode 100644
80index 0000000..7f482b5
81--- /dev/null
82+++ b/tests/fuzz/Makefile.am
83@@ -0,0 +1,13 @@
84+include $(top_srcdir)/includes.mf
85+
86+bin_PROGRAMS = fuzz_ntpd_receive
87+
88+fuzz_ntpd_receive_SOURCES = fuzz_ntpd_receive.c ../../ntpd/ntp_io.c ../../ntpd/ntp_config.c ../../ntpd/ntp_scanner.c ../../ntpd/ntp_parser.y ../../ntpd/ntpd-opts.c
89+fuzz_ntpd_receive_CFLAGS = $(NTP_INCS) -I../../sntp/libopts -I../../ntpd/
90+fuzz_ntpd_receive_LDADD = ../../ntpd/libntpd.a $(LIBPARSE) ../../libntp/libntp.a $(LDADD_LIBNTP) $(LIBOPTS_LDADD) $(PTHREAD_LIBS) $(LIBM) $(LDADD_NTP) $(LSCF) $(LDADD_LIBUTIL)
91+
92+if HAS_SANITIZEFUZZER
93+    fuzz_ntpd_receive_LDFLAGS = $(LIB_FUZZING_ENGINE) -lstdc++ -stdlib=libc++
94+else
95+    fuzz_ntpd_receive_SOURCES += onefile.c
96+endif
97diff --git a/tests/fuzz/fuzz_ntpd_receive.c b/tests/fuzz/fuzz_ntpd_receive.c
98new file mode 100644
99index 0000000..7cb8d99
100--- /dev/null
101+++ b/tests/fuzz/fuzz_ntpd_receive.c
102@@ -0,0 +1,94 @@
103+#include <stddef.h>
104+#include <stdint.h>
105+#include <sys/types.h>
106+#include <sys/stat.h>
107+#include <fcntl.h>
108+
109+#include "config.h"
110+#include "recvbuff.h"
111+#include "ntpd.h"
112+
113+const char *Version = "libntpq 0.3beta";
114+int listen_to_virtual_ips = TRUE;
115+int mdnstries = 5;
116+char const *progname = "fuzz_ntpd_receive";
117+#ifdef HAVE_WORKING_FORK
118+int    waitsync_fd_to_close = -1;    /* -w/--wait-sync */
119+#endif
120+int yydebug=0;
121+
122+static int initialized = 0;
123+int sockfd;
124+uint8_t itf_index;
125+
126+void fuzz_itf_selecter(void * data, interface_info_t * itf) {
127+    endpt **ep = (endpt **)data;
128+    if (itf_index == 0) {
129+        *ep = itf->ep;
130+    }
131+    itf_index--;
132+}
133+
134+int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
135+    struct recvbuf rbufp;
136+
137+    if (initialized == 0) {
138+        sockfd = open("/dev/null", O_RDWR );
139+        //adds interfaces
140+        init_io();
141+        init_auth();
142+        init_util();
143+        init_restrict();
144+        init_mon();
145+        init_timer();
146+        init_lib();
147+        init_request();
148+        init_control();
149+        init_peer();
150+        init_proto();
151+        init_loopfilter();
152+        io_open_sockets();
153+        initialized = 1;
154+    }
155+
156+    if (Size < sizeof(l_fp)) {
157+        return 0;
158+    }
159+    memcpy(&rbufp.recv_time, Data, sizeof(l_fp));
160+    Data += sizeof(l_fp);
161+    Size -= sizeof(l_fp);
162+
163+    if (Size < sizeof(sockaddr_u)) {
164+        return 0;
165+    }
166+    memcpy(&rbufp.srcadr, Data, sizeof(sockaddr_u));
167+    memcpy(&rbufp.recv_srcadr, &rbufp.srcadr, sizeof(sockaddr_u));
168+    Data += sizeof(sockaddr_u);
169+    Size -= sizeof(sockaddr_u);
170+
171+    if (Size < 1) {
172+        return 0;
173+    }
174+    itf_index = Data[0];
175+    rbufp.dstadr = NULL;
176+    interface_enumerate(fuzz_itf_selecter, &rbufp.dstadr);
177+    if (rbufp.dstadr == NULL) {
178+        return 0;
179+    }
180+    Data++;
181+    Size--;
182+
183+    if (Size > RX_BUFF_SIZE) {
184+        Size = RX_BUFF_SIZE;
185+    }
186+    rbufp.recv_length = Size;
187+    memcpy(rbufp.recv_buffer, Data, Size);
188+
189+    rbufp.msg_flags = 0;
190+    rbufp.used = 0;
191+    rbufp.link = NULL;
192+    rbufp.fd = sockfd;
193+
194+    receive(&rbufp);
195+    return 0;
196+}
197diff --git a/tests/fuzz/onefile.c b/tests/fuzz/onefile.c
198new file mode 100644
199index 0000000..74be306
200--- /dev/null
201+++ b/tests/fuzz/onefile.c
202@@ -0,0 +1,51 @@
203+#include <stdint.h>
204+#include <stdlib.h>
205+#include <stdio.h>
206+
207+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
208+
209+int main(int argc, char** argv)
210+{
211+    FILE * fp;
212+    uint8_t *Data;
213+    size_t Size;
214+
215+    if (argc != 2) {
216+        return 1;
217+    }
218+    //opens the file, get its size, and reads it into a buffer
219+    fp = fopen(argv[1], "rb");
220+    if (fp == NULL) {
221+        return 2;
222+    }
223+    if (fseek(fp, 0L, SEEK_END) != 0) {
224+        fclose(fp);
225+        return 2;
226+    }
227+    Size = ftell(fp);
228+    if (Size == (size_t) -1) {
229+        fclose(fp);
230+        return 2;
231+    }
232+    if (fseek(fp, 0L, SEEK_SET) != 0) {
233+        fclose(fp);
234+        return 2;
235+    }
236+    Data = malloc(Size);
237+    if (Data == NULL) {
238+        fclose(fp);
239+        return 2;
240+    }
241+    if (fread(Data, Size, 1, fp) != 1) {
242+        fclose(fp);
243+        free(Data);
244+        return 2;
245+    }
246+
247+    //lauch fuzzer
248+    LLVMFuzzerTestOneInput(Data, Size);
249+    free(Data);
250+    fclose(fp);
251+    return 0;
252+}
253+
254