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