You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
254 lines
6.6 KiB
254 lines
6.6 KiB
diff --git a/configure.ac b/configure.ac
|
|
index 7975d31..528861c 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -4399,6 +4399,37 @@ AC_DEFINE_UNQUOTED([DYNAMIC_INTERLEAVE], [$ntp_dynamic_interleave],
|
|
[support dynamic interleave?])
|
|
AC_MSG_RESULT([$ntp_ok])
|
|
|
|
+AC_ARG_ENABLE(fuzztargets,
|
|
+ AS_HELP_STRING([--enable-fuzztargets], [Enable fuzz targets]),[enable_fuzztargets=$enableval],[enable_fuzztargets=no])
|
|
+AM_CONDITIONAL([BUILD_FUZZTARGETS], [test "x$enable_fuzztargets" = "xyes"])
|
|
+AS_IF([test "x$enable_fuzztargets" = "xyes"], [
|
|
+ AC_PROG_CXX
|
|
+ AC_LANG_PUSH(C++)
|
|
+ AS_IF([test "x$LIB_FUZZING_ENGINE" = "x"], [
|
|
+ LIB_FUZZING_ENGINE=-fsanitize=fuzzer
|
|
+ AC_SUBST(LIB_FUZZING_ENGINE)
|
|
+ ])
|
|
+ tmp_saved_flags=$[]_AC_LANG_PREFIX[]FLAGS
|
|
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $LIB_FUZZING_ENGINE"
|
|
+ AC_MSG_CHECKING([whether $CXX accepts $LIB_FUZZING_ENGINE])
|
|
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
|
+#include <sys/types.h>
|
|
+extern "C" int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size);
|
|
+extern "C" int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size) {
|
|
+(void)Data;
|
|
+(void)Size;
|
|
+return 0;
|
|
+}
|
|
+ ]])],
|
|
+ [ AC_MSG_RESULT(yes)
|
|
+ has_sanitizefuzzer=yes],
|
|
+ [ AC_MSG_RESULT(no) ]
|
|
+ )
|
|
+ _AC_LANG_PREFIX[]FLAGS=$tmp_saved_flags, []
|
|
+ AC_LANG_POP()
|
|
+])
|
|
+AM_CONDITIONAL([HAS_SANITIZEFUZZER], [test "x$has_sanitizefuzzer" = "xyes"])
|
|
+
|
|
NTP_UNITYBUILD
|
|
|
|
dnl gtest is needed for our tests subdirs. It would be nice if we could
|
|
@@ -4459,6 +4490,7 @@ AC_CONFIG_FILES([tests/ntpd/Makefile])
|
|
AC_CONFIG_FILES([tests/ntpq/Makefile])
|
|
AC_CONFIG_FILES([tests/sandbox/Makefile])
|
|
AC_CONFIG_FILES([tests/sec-2853/Makefile])
|
|
+AC_CONFIG_FILES([tests/fuzz/Makefile])
|
|
AC_CONFIG_FILES([util/Makefile])
|
|
|
|
perllibdir="${datadir}/ntp/lib"
|
|
diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c
|
|
index 7c3fdd4..190a373 100644
|
|
--- a/ntpd/ntp_io.c
|
|
+++ b/ntpd/ntp_io.c
|
|
@@ -503,7 +503,11 @@ io_open_sockets(void)
|
|
* Create the sockets
|
|
*/
|
|
BLOCKIO();
|
|
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
+ create_sockets(4123);
|
|
+#else
|
|
create_sockets(NTP_PORT);
|
|
+#endif
|
|
UNBLOCKIO();
|
|
|
|
init_async_notifications();
|
|
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
|
index af502b9..60a2379 100644
|
|
--- a/tests/Makefile.am
|
|
+++ b/tests/Makefile.am
|
|
@@ -10,3 +10,6 @@ SUBDIRS += \
|
|
sec-2853 \
|
|
$(NULL)
|
|
|
|
+if BUILD_FUZZTARGETS
|
|
+ SUBDIRS += fuzz
|
|
+endif
|
|
diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am
|
|
new file mode 100644
|
|
index 0000000..7f482b5
|
|
--- /dev/null
|
|
+++ b/tests/fuzz/Makefile.am
|
|
@@ -0,0 +1,13 @@
|
|
+include $(top_srcdir)/includes.mf
|
|
+
|
|
+bin_PROGRAMS = fuzz_ntpd_receive
|
|
+
|
|
+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
|
|
+fuzz_ntpd_receive_CFLAGS = $(NTP_INCS) -I../../sntp/libopts -I../../ntpd/
|
|
+fuzz_ntpd_receive_LDADD = ../../ntpd/libntpd.a $(LIBPARSE) ../../libntp/libntp.a $(LDADD_LIBNTP) $(LIBOPTS_LDADD) $(PTHREAD_LIBS) $(LIBM) $(LDADD_NTP) $(LSCF) $(LDADD_LIBUTIL)
|
|
+
|
|
+if HAS_SANITIZEFUZZER
|
|
+ fuzz_ntpd_receive_LDFLAGS = $(LIB_FUZZING_ENGINE) -lstdc++ -stdlib=libc++
|
|
+else
|
|
+ fuzz_ntpd_receive_SOURCES += onefile.c
|
|
+endif
|
|
diff --git a/tests/fuzz/fuzz_ntpd_receive.c b/tests/fuzz/fuzz_ntpd_receive.c
|
|
new file mode 100644
|
|
index 0000000..7cb8d99
|
|
--- /dev/null
|
|
+++ b/tests/fuzz/fuzz_ntpd_receive.c
|
|
@@ -0,0 +1,94 @@
|
|
+#include <stddef.h>
|
|
+#include <stdint.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <fcntl.h>
|
|
+
|
|
+#include "config.h"
|
|
+#include "recvbuff.h"
|
|
+#include "ntpd.h"
|
|
+
|
|
+const char *Version = "libntpq 0.3beta";
|
|
+int listen_to_virtual_ips = TRUE;
|
|
+int mdnstries = 5;
|
|
+char const *progname = "fuzz_ntpd_receive";
|
|
+#ifdef HAVE_WORKING_FORK
|
|
+int waitsync_fd_to_close = -1; /* -w/--wait-sync */
|
|
+#endif
|
|
+int yydebug=0;
|
|
+
|
|
+static int initialized = 0;
|
|
+int sockfd;
|
|
+uint8_t itf_index;
|
|
+
|
|
+void fuzz_itf_selecter(void * data, interface_info_t * itf) {
|
|
+ endpt **ep = (endpt **)data;
|
|
+ if (itf_index == 0) {
|
|
+ *ep = itf->ep;
|
|
+ }
|
|
+ itf_index--;
|
|
+}
|
|
+
|
|
+int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
|
|
+ struct recvbuf rbufp;
|
|
+
|
|
+ if (initialized == 0) {
|
|
+ sockfd = open("/dev/null", O_RDWR );
|
|
+ //adds interfaces
|
|
+ init_io();
|
|
+ init_auth();
|
|
+ init_util();
|
|
+ init_restrict();
|
|
+ init_mon();
|
|
+ init_timer();
|
|
+ init_lib();
|
|
+ init_request();
|
|
+ init_control();
|
|
+ init_peer();
|
|
+ init_proto();
|
|
+ init_loopfilter();
|
|
+ io_open_sockets();
|
|
+ initialized = 1;
|
|
+ }
|
|
+
|
|
+ if (Size < sizeof(l_fp)) {
|
|
+ return 0;
|
|
+ }
|
|
+ memcpy(&rbufp.recv_time, Data, sizeof(l_fp));
|
|
+ Data += sizeof(l_fp);
|
|
+ Size -= sizeof(l_fp);
|
|
+
|
|
+ if (Size < sizeof(sockaddr_u)) {
|
|
+ return 0;
|
|
+ }
|
|
+ memcpy(&rbufp.srcadr, Data, sizeof(sockaddr_u));
|
|
+ memcpy(&rbufp.recv_srcadr, &rbufp.srcadr, sizeof(sockaddr_u));
|
|
+ Data += sizeof(sockaddr_u);
|
|
+ Size -= sizeof(sockaddr_u);
|
|
+
|
|
+ if (Size < 1) {
|
|
+ return 0;
|
|
+ }
|
|
+ itf_index = Data[0];
|
|
+ rbufp.dstadr = NULL;
|
|
+ interface_enumerate(fuzz_itf_selecter, &rbufp.dstadr);
|
|
+ if (rbufp.dstadr == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+ Data++;
|
|
+ Size--;
|
|
+
|
|
+ if (Size > RX_BUFF_SIZE) {
|
|
+ Size = RX_BUFF_SIZE;
|
|
+ }
|
|
+ rbufp.recv_length = Size;
|
|
+ memcpy(rbufp.recv_buffer, Data, Size);
|
|
+
|
|
+ rbufp.msg_flags = 0;
|
|
+ rbufp.used = 0;
|
|
+ rbufp.link = NULL;
|
|
+ rbufp.fd = sockfd;
|
|
+
|
|
+ receive(&rbufp);
|
|
+ return 0;
|
|
+}
|
|
diff --git a/tests/fuzz/onefile.c b/tests/fuzz/onefile.c
|
|
new file mode 100644
|
|
index 0000000..74be306
|
|
--- /dev/null
|
|
+++ b/tests/fuzz/onefile.c
|
|
@@ -0,0 +1,51 @@
|
|
+#include <stdint.h>
|
|
+#include <stdlib.h>
|
|
+#include <stdio.h>
|
|
+
|
|
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
|
|
+
|
|
+int main(int argc, char** argv)
|
|
+{
|
|
+ FILE * fp;
|
|
+ uint8_t *Data;
|
|
+ size_t Size;
|
|
+
|
|
+ if (argc != 2) {
|
|
+ return 1;
|
|
+ }
|
|
+ //opens the file, get its size, and reads it into a buffer
|
|
+ fp = fopen(argv[1], "rb");
|
|
+ if (fp == NULL) {
|
|
+ return 2;
|
|
+ }
|
|
+ if (fseek(fp, 0L, SEEK_END) != 0) {
|
|
+ fclose(fp);
|
|
+ return 2;
|
|
+ }
|
|
+ Size = ftell(fp);
|
|
+ if (Size == (size_t) -1) {
|
|
+ fclose(fp);
|
|
+ return 2;
|
|
+ }
|
|
+ if (fseek(fp, 0L, SEEK_SET) != 0) {
|
|
+ fclose(fp);
|
|
+ return 2;
|
|
+ }
|
|
+ Data = malloc(Size);
|
|
+ if (Data == NULL) {
|
|
+ fclose(fp);
|
|
+ return 2;
|
|
+ }
|
|
+ if (fread(Data, Size, 1, fp) != 1) {
|
|
+ fclose(fp);
|
|
+ free(Data);
|
|
+ return 2;
|
|
+ }
|
|
+
|
|
+ //lauch fuzzer
|
|
+ LLVMFuzzerTestOneInput(Data, Size);
|
|
+ free(Data);
|
|
+ fclose(fp);
|
|
+ return 0;
|
|
+}
|
|
+
|