blob: d28e15f31e380e64705c287aad0bcc9fae5294b9 [file] [log] [blame]
dobinedf9f8d2018-01-21 13:57:02 +01001#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>
dobinedf9f8d2018-01-21 13:57:02 +010022#include <sys/socket.h>
Robert Swiecki56276192018-01-21 15:43:02 +010023#include <sys/types.h>
dobinedf9f8d2018-01-21 13:57:02 +010024#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
dobinedf9f8d2018-01-21 13:57:02 +010036bool 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
Robert Swiecki56276192018-01-21 15:43:02 +010052bool fuzz_prepareSocketFuzzer(run_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +010053 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->socketFuzzerData.clientSocket, "Fuzz", 4, 0);
Robert Swiecki56276192018-01-21 15:43:02 +010058 if (ret < 0) {
Robert Swieckif3ecc0e2018-01-21 15:42:22 +010059 LOG_F("fuzz_prepareSocketFuzzer: received: %zu", ret);
dobinedf9f8d2018-01-21 13:57:02 +010060 return false;
61 }
62
63 return true;
64}
65
66/* Return values:
67 0: error
68 1: okay
69 2: target unresponsive
70*/
Robert Swiecki56276192018-01-21 15:43:02 +010071int fuzz_waitforSocketFuzzer(run_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +010072 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->socketFuzzerData.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
Robert Swiecki56276192018-01-21 15:43:02 +010081 if (ret < 0) {
Robert Swieckif3ecc0e2018-01-21 15:42:22 +010082 LOG_F("fuzz_waitforSocketFuzzer: received: %zu", ret);
dobinedf9f8d2018-01-21 13:57:02 +010083 return 0;
84 }
85
Robert Swiecki56276192018-01-21 15:43:02 +010086 if (memcmp(buf, "okay", 4) == 0) {
dobinedf9f8d2018-01-21 13:57:02 +010087 return 1;
Robert Swiecki56276192018-01-21 15:43:02 +010088 } else if (memcmp(buf, "bad!", 4) == 0) {
dobinedf9f8d2018-01-21 13:57:02 +010089 return 2;
90 }
91
92 return 0;
93}
94
Robert Swiecki56276192018-01-21 15:43:02 +010095bool fuzz_notifySocketFuzzerNewCov(honggfuzz_t* hfuzz) {
dobinedf9f8d2018-01-21 13:57:02 +010096 ssize_t ret;
97
98 // Tell the fuzzer that the thing he sent reached new BB's
99 ret = send(hfuzz->socketFuzzerData.clientSocket, "New!", 4, 0);
100 LOG_D("fuzz_notifySocketFuzzer: SEND: New!");
Robert Swiecki56276192018-01-21 15:43:02 +0100101 if (ret < 0) {
Robert Swieckif3ecc0e2018-01-21 15:42:22 +0100102 LOG_F("fuzz_notifySocketFuzzer: sent: %zu", ret);
dobinedf9f8d2018-01-21 13:57:02 +0100103 return false;
104 }
105
106 return true;
107}
108
Robert Swiecki56276192018-01-21 15:43:02 +0100109bool fuzz_notifySocketFuzzerCrash(run_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +0100110 ssize_t ret;
111
112 ret = send(run->global->socketFuzzerData.clientSocket, "Cras", 4, 0);
113 LOG_D("fuzz_notifySocketFuzzer: SEND: Crash");
Robert Swiecki56276192018-01-21 15:43:02 +0100114 if (ret < 0) {
Robert Swieckif3ecc0e2018-01-21 15:42:22 +0100115 LOG_F("fuzz_notifySocketFuzzer: sent: %zu", ret);
dobinedf9f8d2018-01-21 13:57:02 +0100116 return false;
117 }
118
119 return true;
120}
121
Robert Swiecki56276192018-01-21 15:43:02 +0100122bool setupSocketFuzzer(honggfuzz_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +0100123 int s, len;
124 socklen_t t;
125 struct sockaddr_un local, remote;
126 char socketPath[512];
Robert Swiecki56276192018-01-21 15:43:02 +0100127 // snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid());
dobinedf9f8d2018-01-21 13:57:02 +0100128 snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket");
129
130 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
131 perror("socket");
132 return false;
133 }
134
135 local.sun_family = AF_UNIX;
136 strcpy(local.sun_path, socketPath);
137 unlink(local.sun_path);
138 len = strlen(local.sun_path) + sizeof(local.sun_family);
Robert Swiecki56276192018-01-21 15:43:02 +0100139 if (bind(s, (struct sockaddr*)&local, len) == -1) {
dobinedf9f8d2018-01-21 13:57:02 +0100140 perror("bind");
141 return false;
142 }
143
144 if (listen(s, 5) == -1) {
145 perror("listen");
146 return false;
147 }
148
149 printf("Waiting for SocketFuzzer connection on socket: %s\n", socketPath);
150 t = sizeof(remote);
Robert Swiecki56276192018-01-21 15:43:02 +0100151 if ((run->socketFuzzerData.clientSocket = accept(s, (struct sockaddr*)&remote, &t)) == -1) {
dobinedf9f8d2018-01-21 13:57:02 +0100152 perror("accept");
153 return false;
154 }
155
156 run->socketFuzzerData.serverSocket = s;
157 printf("A SocketFuzzer client connected. Continuing.\n");
158
159 return true;
160}
161
162void cleanupSocketFuzzer() {
163 char socketPath[512];
Robert Swiecki56276192018-01-21 15:43:02 +0100164 // snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid());
dobinedf9f8d2018-01-21 13:57:02 +0100165 snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket");
166 unlink(socketPath);
167}