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