254 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
| 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;
 | |
| +}
 | |
| +
 |