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
fuzz_waitForExternalInput(run_t * run)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
fuzz_prepareSocketFuzzer(run_t * run)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 */
fuzz_waitforSocketFuzzer(run_t * run)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
fuzz_notifySocketFuzzerNewCov(honggfuzz_t * hfuzz)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
fuzz_notifySocketFuzzerCrash(run_t * run)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
setupSocketFuzzer(honggfuzz_t * run)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
cleanupSocketFuzzer()161 void cleanupSocketFuzzer() {
162 char socketPath[512];
163 snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid());
164 unlink(socketPath);
165 }
166