diff options
-rw-r--r-- | pcap-rpcap.c | 4 | ||||
-rw-r--r-- | rpcapd/daemon.c | 10 | ||||
-rw-r--r-- | sockutils.c | 39 | ||||
-rw-r--r-- | testprogs/fuzz/CMakeLists.txt | 23 | ||||
-rw-r--r-- | testprogs/fuzz/fuzz_rclient.c | 56 | ||||
-rw-r--r-- | testprogs/fuzz/fuzz_rserver.c | 56 |
6 files changed, 185 insertions, 3 deletions
diff --git a/pcap-rpcap.c b/pcap-rpcap.c index 787b67a8..a480f9e0 100644 --- a/pcap-rpcap.c +++ b/pcap-rpcap.c @@ -417,7 +417,11 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch */ FD_SET(pr->rmt_sockdata, &rfds); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + retval = 1; +#else retval = select((int) pr->rmt_sockdata + 1, &rfds, NULL, NULL, &tv); +#endif if (retval == -1) { diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c index 67c61e55..7a31a2b3 100644 --- a/rpcapd/daemon.c +++ b/rpcapd/daemon.c @@ -756,8 +756,11 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, tv.tv_usec = 0; FD_SET(pars.sockctrl, &rfds); - +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + retval = 1; +#else retval = select((int)pars.sockctrl + 1, &rfds, NULL, NULL, &tv); +#endif if (retval == -1) { sock_geterror("select() failed", errmsgbuf, PCAP_ERRBUF_SIZE); @@ -1105,6 +1108,9 @@ end: session = NULL; } + if (passiveClients) { + free(passiveClients); + } // // Finish using the SSL handle for the control socket, if we // have an SSL connection, and close the control socket. @@ -2853,6 +2859,7 @@ daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *socka */ void sleep_secs(int secs) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #ifdef _WIN32 Sleep(secs*1000); #else @@ -2864,6 +2871,7 @@ void sleep_secs(int secs) while (secs_remaining != 0) secs_remaining = sleep(secs_remaining); #endif +#endif } /* diff --git a/sockutils.c b/sockutils.c index 1221b18f..dd43a315 100644 --- a/sockutils.c +++ b/sockutils.c @@ -120,6 +120,29 @@ static int sock_ismcastaddr(const struct sockaddr *saddr); * * ****************************************************/ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +const uint8_t *fuzzBuffer; +size_t fuzzSize; +size_t fuzzPos; + +void sock_initfuzz(const uint8_t *Data, size_t Size) { + fuzzPos = 0; + fuzzSize = Size; + fuzzBuffer = Data; +} + +static int fuzz_recv(char *bufp, int remaining) { + if (remaining > fuzzSize - fuzzPos) { + remaining = fuzzSize - fuzzPos; + } + if (fuzzPos < fuzzSize) { + memcpy(bufp, fuzzBuffer + fuzzPos, remaining); + } + fuzzPos += remaining; + return remaining; +} +#endif + /* * Format an error message given an errno value (UN*X) or a Winsock error * (Windows). @@ -415,7 +438,9 @@ SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, */ while (tempaddrinfo) { - +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + break; +#endif if (connect(sock, tempaddrinfo->ai_addr, (int) tempaddrinfo->ai_addrlen) == -1) { size_t msglen; @@ -794,6 +819,9 @@ int sock_send(SOCKET sock, SSL *ssl _U_NOSSL_, const char *buffer, size_t size, if (ssl) return ssl_send(ssl, buffer, remaining, errbuf, errbuflen); #endif +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + nsent = remaining; +#else #ifdef MSG_NOSIGNAL /* * Send with MSG_NOSIGNAL, so that we don't get SIGPIPE @@ -805,6 +833,7 @@ int sock_send(SOCKET sock, SSL *ssl _U_NOSSL_, const char *buffer, size_t size, #else nsent = send(sock, buffer, remaining, 0); #endif +#endif //FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (nsent == -1) { @@ -1004,7 +1033,9 @@ int sock_recv(SOCKET sock, SSL *ssl _U_NOSSL_, void *buffer, size_t size, * Win32. */ for (;;) { -#ifdef HAVE_OPENSSL +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + nread = fuzz_recv(bufp, remaining); +#elif defined(HAVE_OPENSSL) if (ssl) { /* @@ -1158,7 +1189,11 @@ int sock_recv_dgram(SOCKET sock, SSL *ssl _U_NOSSL_, void *buffer, size_t size, #ifdef HAVE_STRUCT_MSGHDR_MSG_FLAGS message.msg_flags = 0; #endif +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + nread = fuzz_recv(buffer, size); +#else nread = recvmsg(sock, &message, 0); +#endif if (nread == -1) { if (errno == EINTR) diff --git a/testprogs/fuzz/CMakeLists.txt b/testprogs/fuzz/CMakeLists.txt index 4a2862f9..67250cca 100644 --- a/testprogs/fuzz/CMakeLists.txt +++ b/testprogs/fuzz/CMakeLists.txt @@ -18,3 +18,26 @@ if(NOT "${SANITIZER_FLAGS}" STREQUAL "") set_target_properties(fuzz_both PROPERTIES LINK_FLAGS "${SANITIZER_FLAGS}") endif() + +if(ENABLE_REMOTE AND "$ENV{CFLAGS}" MATCHES "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION") +add_executable(fuzz_rclient onefile.c fuzz_rclient.c) +target_link_libraries(fuzz_rclient ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(fuzz_rclient PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") +endif() + +add_executable(fuzz_rserver onefile.c fuzz_rserver.c ../../rpcapd/daemon.c) +check_function_exists(crypt HAVE_CRYPT_IN_SYSTEM_LIBRARIES) +if(HAVE_CRYPT_IN_SYSTEM_LIBRARIES) + set(HAVE_CRYPT TRUE) +else(HAVE_CRYPT_IN_SYSTEM_LIBRARIES) + set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} crypt) +endif(HAVE_CRYPT_IN_SYSTEM_LIBRARIES) +target_link_libraries(fuzz_rserver ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) + +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(fuzz_rserver PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") +endif() +endif(ENABLE_REMOTE AND "$ENV{CFLAGS}" MATCHES "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION") diff --git a/testprogs/fuzz/fuzz_rclient.c b/testprogs/fuzz/fuzz_rclient.c new file mode 100644 index 00000000..b5a6a91a --- /dev/null +++ b/testprogs/fuzz/fuzz_rclient.c @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> + +#include <pcap/pcap.h> + +FILE * outfile = NULL; +struct pcap_rmtauth auth; + +void fuzz_openFile(const char * name) { + if (outfile != NULL) { + fclose(outfile); + } + outfile = fopen(name, "w"); + auth.type = RPCAP_RMTAUTH_PWD; + auth.username = "user"; + auth.password = "pass"; +} + +void sock_initfuzz(const uint8_t *Data, size_t Size); +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + pcap_t * pkts; + char errbuf[PCAP_ERRBUF_SIZE]; + const u_char *pkt; + struct pcap_pkthdr *header; + struct pcap_stat stats; + int r; + + //initialization + if (outfile == NULL) { + fuzz_openFile("/dev/null"); + } + + sock_initfuzz(Data, Size); + //initialize structure + pkts = pcap_open("rpcap://127.0.0.1/fuzz.pcap", 0, 0, 1000, &auth, errbuf); + if (pkts == NULL) { + fprintf(outfile, "Couldn't open pcap file %s\n", errbuf); + return 0; + } + + //loop over packets + r = pcap_next_ex(pkts, &header, &pkt); + while (r > 0) { + fprintf(outfile, "packet length=%d/%d\n",header->caplen, header->len); + r = pcap_next_ex(pkts, &header, &pkt); + } + if (pcap_stats(pkts, &stats) == 0) { + fprintf(outfile, "number of packets=%d\n", stats.ps_recv); + } + //close structure + pcap_close(pkts); + + return 0; +} diff --git a/testprogs/fuzz/fuzz_rserver.c b/testprogs/fuzz/fuzz_rserver.c new file mode 100644 index 00000000..c79a3736 --- /dev/null +++ b/testprogs/fuzz/fuzz_rserver.c @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <stdarg.h> + +#include <pcap/pcap.h> + +FILE * outfile = NULL; + +void fuzz_openFile(const char * name) { + if (outfile != NULL) { + fclose(outfile); + } + outfile = fopen(name, "w"); +} + +typedef enum { + LOGPRIO_DEBUG, + LOGPRIO_INFO, + LOGPRIO_WARNING, + LOGPRIO_ERROR +} log_priority; + +void rpcapd_log(log_priority priority, const char *message, ...) +{ + va_list ap; + + va_start(ap, message); + fprintf(outfile, "rpcapd[%d]:", priority); + vfprintf(outfile, message, ap); + putc('\n', outfile); + va_end(ap); +} + +void sock_initfuzz(const uint8_t *Data, size_t Size); +int daemon_serviceloop(int sockctrl, int isactive, char *passiveClients, int nullAuthAllowed, int uses_ssl); + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + int sock; + + //initialization + if (outfile == NULL) { + fuzz_openFile("/dev/null"); + } + + sock_initfuzz(Data, Size); + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == INVALID_SOCKET) { + abort(); + } + //dummy socket, active, null auth allowed, no ssl + daemon_serviceloop(sock, 1, malloc(0), 1, 0); + + return 0; +} |