1 #include <errno.h> 2 #include <fcntl.h> 3 #include <inttypes.h> 4 #include <libgen.h> 5 #include <pthread.h> 6 #include <signal.h> 7 #include <stddef.h> 8 #include <stdint.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <sys/mman.h> 13 #include <sys/param.h> 14 #include <sys/stat.h> 15 #include <sys/time.h> 16 #include <sys/types.h> 17 #include <time.h> 18 #include <unistd.h> 19 20 #include <errno.h> 21 #include <string.h> 22 #include <sys/socket.h> 23 #include <sys/types.h> 24 #include <sys/un.h> 25 #include <unistd.h> 26 27 #include "honggfuzz.h" 28 #include "libhfcommon/common.h" 29 #include "libhfcommon/files.h" 30 #include "libhfcommon/log.h" 31 #include "libhfcommon/ns.h" 32 #include "libhfcommon/util.h" 33 34 #include "socketfuzzer.h" 35 36 bool fuzz_waitForExternalInput(run_t* run) { 37 /* tell the external fuzzer to do his thing */ 38 if (!fuzz_prepareSocketFuzzer(run)) { 39 LOG_F("fuzz_prepareSocketFuzzer() failed"); 40 return false; 41 } 42 43 /* the external fuzzer may inform us of a crash */ 44 int result = fuzz_waitforSocketFuzzer(run); 45 if (result == 2) { 46 return false; 47 } 48 49 return true; 50 } 51 52 bool fuzz_prepareSocketFuzzer(run_t* run) { 53 ssize_t ret; 54 55 // Notify fuzzer that he should send teh things 56 LOG_D("fuzz_prepareSocketFuzzer: SEND Fuzz"); 57 ret = send(run->global->socketFuzzer.clientSocket, "Fuzz", 4, 0); 58 if (ret < 0) { 59 LOG_F("fuzz_prepareSocketFuzzer: received: %zu", ret); 60 return false; 61 } 62 63 return true; 64 } 65 66 /* Return values: 67 0: error 68 1: okay 69 2: target unresponsive 70 */ 71 int fuzz_waitforSocketFuzzer(run_t* run) { 72 ssize_t ret; 73 char buf[16]; 74 75 // Wait until the external fuzzer did his thing 76 bzero(buf, 16); 77 ret = recv(run->global->socketFuzzer.clientSocket, buf, 4, 0); 78 LOG_D("fuzz_waitforSocketFuzzer: RECV: %s", buf); 79 80 // We dont care what we receive, its just to block here 81 if (ret < 0) { 82 LOG_F("fuzz_waitforSocketFuzzer: received: %zu", ret); 83 return 0; 84 } 85 86 if (memcmp(buf, "okay", 4) == 0) { 87 return 1; 88 } else if (memcmp(buf, "bad!", 4) == 0) { 89 return 2; 90 } 91 92 return 0; 93 } 94 95 bool fuzz_notifySocketFuzzerNewCov(honggfuzz_t* hfuzz) { 96 ssize_t ret; 97 98 // Tell the fuzzer that the thing he sent reached new BB's 99 ret = send(hfuzz->socketFuzzer.clientSocket, "New!", 4, 0); 100 LOG_D("fuzz_notifySocketFuzzer: SEND: New!"); 101 if (ret < 0) { 102 LOG_F("fuzz_notifySocketFuzzer: sent: %zu", ret); 103 return false; 104 } 105 106 return true; 107 } 108 109 bool fuzz_notifySocketFuzzerCrash(run_t* run) { 110 ssize_t ret; 111 112 ret = send(run->global->socketFuzzer.clientSocket, "Cras", 4, 0); 113 LOG_D("fuzz_notifySocketFuzzer: SEND: Crash"); 114 if (ret < 0) { 115 LOG_F("fuzz_notifySocketFuzzer: sent: %zu", ret); 116 return false; 117 } 118 119 return true; 120 } 121 122 bool setupSocketFuzzer(honggfuzz_t* run) { 123 int s, len; 124 socklen_t t; 125 struct sockaddr_un local, remote; 126 char socketPath[512]; 127 snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid()); 128 129 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { 130 perror("socket"); 131 return false; 132 } 133 134 local.sun_family = AF_UNIX; 135 strcpy(local.sun_path, socketPath); 136 unlink(local.sun_path); 137 len = strlen(local.sun_path) + sizeof(local.sun_family); 138 if (bind(s, (struct sockaddr*)&local, len) == -1) { 139 perror("bind"); 140 return false; 141 } 142 143 if (listen(s, 5) == -1) { 144 perror("listen"); 145 return false; 146 } 147 148 printf("Waiting for SocketFuzzer connection on socket: %s\n", socketPath); 149 t = sizeof(remote); 150 if ((run->socketFuzzer.clientSocket = accept(s, (struct sockaddr*)&remote, &t)) == -1) { 151 perror("accept"); 152 return false; 153 } 154 155 run->socketFuzzer.serverSocket = s; 156 printf("A SocketFuzzer client connected. Continuing.\n"); 157 158 return true; 159 } 160 161 void cleanupSocketFuzzer() { 162 char socketPath[512]; 163 snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid()); 164 unlink(socketPath); 165 } 166