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