diff options
Diffstat (limited to 'socketfuzzer.c')
-rw-r--r-- | socketfuzzer.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/socketfuzzer.c b/socketfuzzer.c new file mode 100644 index 00000000..14a5f246 --- /dev/null +++ b/socketfuzzer.c @@ -0,0 +1,165 @@ +#include <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <libgen.h> +#include <pthread.h> +#include <signal.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +#include <errno.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/un.h> +#include <unistd.h> + +#include "honggfuzz.h" +#include "libhfcommon/common.h" +#include "libhfcommon/files.h" +#include "libhfcommon/log.h" +#include "libhfcommon/ns.h" +#include "libhfcommon/util.h" + +#include "socketfuzzer.h" + +bool fuzz_waitForExternalInput(run_t* run) { + /* tell the external fuzzer to do his thing */ + if (!fuzz_prepareSocketFuzzer(run)) { + LOG_F("fuzz_prepareSocketFuzzer() failed"); + return false; + } + + /* the external fuzzer may inform us of a crash */ + int result = fuzz_waitforSocketFuzzer(run); + if (result == 2) { + return false; + } + + return true; +} + +bool fuzz_prepareSocketFuzzer(run_t* run) { + ssize_t ret; + + // Notify fuzzer that he should send teh things + LOG_D("fuzz_prepareSocketFuzzer: SEND Fuzz"); + ret = send(run->global->socketFuzzer.clientSocket, "Fuzz", 4, 0); + if (ret < 0) { + LOG_F("fuzz_prepareSocketFuzzer: received: %zu", ret); + return false; + } + + return true; +} + +/* Return values: + 0: error + 1: okay + 2: target unresponsive +*/ +int fuzz_waitforSocketFuzzer(run_t* run) { + ssize_t ret; + char buf[16]; + + // Wait until the external fuzzer did his thing + bzero(buf, 16); + ret = recv(run->global->socketFuzzer.clientSocket, buf, 4, 0); + LOG_D("fuzz_waitforSocketFuzzer: RECV: %s", buf); + + // We dont care what we receive, its just to block here + if (ret < 0) { + LOG_F("fuzz_waitforSocketFuzzer: received: %zu", ret); + return 0; + } + + if (memcmp(buf, "okay", 4) == 0) { + return 1; + } else if (memcmp(buf, "bad!", 4) == 0) { + return 2; + } + + return 0; +} + +bool fuzz_notifySocketFuzzerNewCov(honggfuzz_t* hfuzz) { + ssize_t ret; + + // Tell the fuzzer that the thing he sent reached new BB's + ret = send(hfuzz->socketFuzzer.clientSocket, "New!", 4, 0); + LOG_D("fuzz_notifySocketFuzzer: SEND: New!"); + if (ret < 0) { + LOG_F("fuzz_notifySocketFuzzer: sent: %zu", ret); + return false; + } + + return true; +} + +bool fuzz_notifySocketFuzzerCrash(run_t* run) { + ssize_t ret; + + ret = send(run->global->socketFuzzer.clientSocket, "Cras", 4, 0); + LOG_D("fuzz_notifySocketFuzzer: SEND: Crash"); + if (ret < 0) { + LOG_F("fuzz_notifySocketFuzzer: sent: %zu", ret); + return false; + } + + return true; +} + +bool setupSocketFuzzer(honggfuzz_t* run) { + int s, len; + socklen_t t; + struct sockaddr_un local, remote; + char socketPath[512]; + snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid()); + + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + perror("socket"); + return false; + } + + local.sun_family = AF_UNIX; + strcpy(local.sun_path, socketPath); + unlink(local.sun_path); + len = strlen(local.sun_path) + sizeof(local.sun_family); + if (bind(s, (struct sockaddr*)&local, len) == -1) { + perror("bind"); + return false; + } + + if (listen(s, 5) == -1) { + perror("listen"); + return false; + } + + printf("Waiting for SocketFuzzer connection on socket: %s\n", socketPath); + t = sizeof(remote); + if ((run->socketFuzzer.clientSocket = accept(s, (struct sockaddr*)&remote, &t)) == -1) { + perror("accept"); + return false; + } + + run->socketFuzzer.serverSocket = s; + printf("A SocketFuzzer client connected. Continuing.\n"); + + return true; +} + +void cleanupSocketFuzzer() { + char socketPath[512]; + snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid()); + unlink(socketPath); +} |