#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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); }