diff options
| author | Joseph Mingrone <jrm@FreeBSD.org> | 2023-03-27 18:45:17 +0000 |
|---|---|---|
| committer | Joseph Mingrone <jrm@FreeBSD.org> | 2023-03-27 18:45:17 +0000 |
| commit | 35af88c96350eb786f1198dfb6b29a171016e6bf (patch) | |
| tree | e883c1f8391d5ca1afd57abd8ed9d2cd7c274b0b /testprogs/fuzz | |
| parent | 20616273d52132557e786a8aea1637be4c218a08 (diff) | |
Diffstat (limited to 'testprogs/fuzz')
| -rw-r--r-- | testprogs/fuzz/CMakeLists.txt | 43 | ||||
| -rw-r--r-- | testprogs/fuzz/fuzz_both.c | 101 | ||||
| -rw-r--r-- | testprogs/fuzz/fuzz_both.options | 2 | ||||
| -rw-r--r-- | testprogs/fuzz/fuzz_filter.c | 43 | ||||
| -rw-r--r-- | testprogs/fuzz/fuzz_filter.options | 2 | ||||
| -rw-r--r-- | testprogs/fuzz/fuzz_pcap.c | 80 | ||||
| -rw-r--r-- | testprogs/fuzz/fuzz_pcap.options | 2 | ||||
| -rw-r--r-- | testprogs/fuzz/onefile.c | 54 |
8 files changed, 327 insertions, 0 deletions
diff --git a/testprogs/fuzz/CMakeLists.txt b/testprogs/fuzz/CMakeLists.txt new file mode 100644 index 000000000000..67250cca4349 --- /dev/null +++ b/testprogs/fuzz/CMakeLists.txt @@ -0,0 +1,43 @@ +add_executable(fuzz_pcap onefile.c fuzz_pcap.c) +target_link_libraries(fuzz_pcap ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(fuzz_pcap PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") +endif() + +add_executable(fuzz_filter onefile.c fuzz_filter.c) +target_link_libraries(fuzz_filter ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(fuzz_filter PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") +endif() + +add_executable(fuzz_both onefile.c fuzz_both.c) +target_link_libraries(fuzz_both ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) +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_both.c b/testprogs/fuzz/fuzz_both.c new file mode 100644 index 000000000000..59e3d404103d --- /dev/null +++ b/testprogs/fuzz/fuzz_both.c @@ -0,0 +1,101 @@ +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> + +#include <pcap/pcap.h> + +FILE * outfile = NULL; + +static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) { + FILE * fd; + if (remove(name) != 0) { + if (errno != ENOENT) { + printf("failed remove, errno=%d\n", errno); + return -1; + } + } + fd = fopen(name, "wb"); + if (fd == NULL) { + printf("failed open, errno=%d\n", errno); + return -2; + } + if (fwrite (Data, 1, Size, fd) != Size) { + fclose(fd); + return -3; + } + fclose(fd); + return 0; +} + +void fuzz_openFile(const char * name) { + if (outfile != NULL) { + fclose(outfile); + } + outfile = fopen(name, "w"); +} + +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; + int r; + size_t filterSize; + char * filter; + struct bpf_program bpf; + + + //initialize output file + if (outfile == NULL) { + outfile = fopen("/dev/null", "w"); + if (outfile == NULL) { + return 0; + } + } + + if (Size < 1) { + return 0; + } + filterSize = Data[0]; + if (Size < 1+filterSize || filterSize == 0) { + return 0; + } + + //rewrite buffer to a file as libpcap does not have buffer inputs + if (bufferToFile("/tmp/fuzz.pcap", Data+1+filterSize, Size-(1+filterSize)) < 0) { + return 0; + } + + //initialize structure + pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf); + if (pkts == NULL) { + fprintf(outfile, "Couldn't open pcap file %s\n", errbuf); + return 0; + } + + filter = malloc(filterSize); + memcpy(filter, Data+1, filterSize); + //null terminate string + filter[filterSize-1] = 0; + + if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) { + //loop over packets + r = pcap_next_ex(pkts, &header, &pkt); + while (r > 0) { + //checks filter + fprintf(outfile, "packet length=%d/%d filter=%d\n",header->caplen, header->len, pcap_offline_filter(&bpf, header, pkt)); + r = pcap_next_ex(pkts, &header, &pkt); + } + //close structure + pcap_close(pkts); + pcap_freecode(&bpf); + } + else { + pcap_close(pkts); + } + free(filter); + + return 0; +} diff --git a/testprogs/fuzz/fuzz_both.options b/testprogs/fuzz/fuzz_both.options new file mode 100644 index 000000000000..0824b19fab47 --- /dev/null +++ b/testprogs/fuzz/fuzz_both.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/testprogs/fuzz/fuzz_filter.c b/testprogs/fuzz/fuzz_filter.c new file mode 100644 index 000000000000..de350672797f --- /dev/null +++ b/testprogs/fuzz/fuzz_filter.c @@ -0,0 +1,43 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <pcap/pcap.h> + +void fuzz_openFile(const char * name){ + //do nothing +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + pcap_t * pkts; + struct bpf_program bpf; + char * filter; + + //we need at least 1 byte for linktype + if (Size < 1) { + return 0; + } + + //initialize structure snaplen = 65535 + pkts = pcap_open_dead(Data[Size-1], 0xFFFF); + if (pkts == NULL) { + printf("pcap_open_dead failed\n"); + return 0; + } + filter = malloc(Size); + memcpy(filter, Data, Size); + //null terminate string + filter[Size-1] = 0; + + if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) { + pcap_setfilter(pkts, &bpf); + pcap_close(pkts); + pcap_freecode(&bpf); + } + else { + pcap_close(pkts); + } + free(filter); + + return 0; +} diff --git a/testprogs/fuzz/fuzz_filter.options b/testprogs/fuzz/fuzz_filter.options new file mode 100644 index 000000000000..9fda93fcb340 --- /dev/null +++ b/testprogs/fuzz/fuzz_filter.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 4096 diff --git a/testprogs/fuzz/fuzz_pcap.c b/testprogs/fuzz/fuzz_pcap.c new file mode 100644 index 000000000000..fba5312fcaf2 --- /dev/null +++ b/testprogs/fuzz/fuzz_pcap.c @@ -0,0 +1,80 @@ +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> + +#include <pcap/pcap.h> + +FILE * outfile = NULL; + +static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) { + FILE * fd; + if (remove(name) != 0) { + if (errno != ENOENT) { + printf("failed remove, errno=%d\n", errno); + return -1; + } + } + fd = fopen(name, "wb"); + if (fd == NULL) { + printf("failed open, errno=%d\n", errno); + return -2; + } + if (fwrite (Data, 1, Size, fd) != Size) { + fclose(fd); + return -3; + } + fclose(fd); + return 0; +} + +void fuzz_openFile(const char * name) { + if (outfile != NULL) { + fclose(outfile); + } + outfile = fopen(name, "w"); +} + +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; + + //initialize output file + if (outfile == NULL) { + outfile = fopen("/dev/null", "w"); + if (outfile == NULL) { + return 0; + } + } + + //rewrite buffer to a file as libpcap does not have buffer inputs + if (bufferToFile("/tmp/fuzz.pcap", Data, Size) < 0) { + return 0; + } + + //initialize structure + pkts = pcap_open_offline("/tmp/fuzz.pcap", 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) { + //TODO pcap_offline_filter + 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_pcap.options b/testprogs/fuzz/fuzz_pcap.options new file mode 100644 index 000000000000..0824b19fab47 --- /dev/null +++ b/testprogs/fuzz/fuzz_pcap.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/testprogs/fuzz/onefile.c b/testprogs/fuzz/onefile.c new file mode 100644 index 000000000000..690a63bdc433 --- /dev/null +++ b/testprogs/fuzz/onefile.c @@ -0,0 +1,54 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); +void fuzz_openFile(const char * name); + +int main(int argc, char** argv) +{ + FILE * fp; + uint8_t *Data; + size_t Size; + + if (argc == 3) { + fuzz_openFile(argv[2]); + } else 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; + } + + //launch fuzzer + LLVMFuzzerTestOneInput(Data, Size); + free(Data); + fclose(fp); + return 0; +} + |
