• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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