blob: d941e340ceeee43b6606c17e2d4c636dc6556ef1 [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");
dobinedf9f8d2018-01-21 13:57:02 +010040 }
41
42 /* the external fuzzer may inform us of a crash */
43 int result = fuzz_waitforSocketFuzzer(run);
44 if (result == 2) {
45 return false;
46 }
47
48 return true;
49}
50
Robert Swiecki56276192018-01-21 15:43:02 +010051bool fuzz_prepareSocketFuzzer(run_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +010052 // Notify fuzzer that he should send teh things
53 LOG_D("fuzz_prepareSocketFuzzer: SEND Fuzz");
Robert Swiecki251ee7c2019-04-17 21:56:22 +020054 return files_sendToSocket(
55 run->global->socketFuzzer.clientSocket, (uint8_t*)"Fuzz", strlen("Fuzz"));
dobinedf9f8d2018-01-21 13:57:02 +010056}
57
58/* Return values:
59 0: error
60 1: okay
61 2: target unresponsive
62*/
Robert Swiecki56276192018-01-21 15:43:02 +010063int fuzz_waitforSocketFuzzer(run_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +010064 ssize_t ret;
Robert Swiecki251ee7c2019-04-17 21:56:22 +020065 uint8_t buf[16];
dobinedf9f8d2018-01-21 13:57:02 +010066
67 // Wait until the external fuzzer did his thing
68 bzero(buf, 16);
Robert Swiecki251ee7c2019-04-17 21:56:22 +020069 ret = files_readFromFd(run->global->socketFuzzer.clientSocket, buf, 4);
dobinedf9f8d2018-01-21 13:57:02 +010070 LOG_D("fuzz_waitforSocketFuzzer: RECV: %s", buf);
71
72 // We dont care what we receive, its just to block here
Robert Swiecki56276192018-01-21 15:43:02 +010073 if (ret < 0) {
Robert Swieckif3ecc0e2018-01-21 15:42:22 +010074 LOG_F("fuzz_waitforSocketFuzzer: received: %zu", ret);
dobinedf9f8d2018-01-21 13:57:02 +010075 }
76
Robert Swiecki56276192018-01-21 15:43:02 +010077 if (memcmp(buf, "okay", 4) == 0) {
dobinedf9f8d2018-01-21 13:57:02 +010078 return 1;
Robert Swiecki56276192018-01-21 15:43:02 +010079 } else if (memcmp(buf, "bad!", 4) == 0) {
dobinedf9f8d2018-01-21 13:57:02 +010080 return 2;
81 }
82
83 return 0;
84}
85
Robert Swiecki56276192018-01-21 15:43:02 +010086bool fuzz_notifySocketFuzzerNewCov(honggfuzz_t* hfuzz) {
dobinedf9f8d2018-01-21 13:57:02 +010087 // Tell the fuzzer that the thing he sent reached new BB's
Robert Swiecki251ee7c2019-04-17 21:56:22 +020088 bool ret = files_sendToSocket(hfuzz->socketFuzzer.clientSocket, (uint8_t*)"New!", 4);
dobinedf9f8d2018-01-21 13:57:02 +010089 LOG_D("fuzz_notifySocketFuzzer: SEND: New!");
Robert Swiecki251ee7c2019-04-17 21:56:22 +020090 if (!ret) {
91 LOG_F("fuzz_notifySocketFuzzer");
dobinedf9f8d2018-01-21 13:57:02 +010092 }
93
94 return true;
95}
96
Robert Swiecki56276192018-01-21 15:43:02 +010097bool fuzz_notifySocketFuzzerCrash(run_t* run) {
Robert Swiecki251ee7c2019-04-17 21:56:22 +020098 bool ret = files_sendToSocket(run->global->socketFuzzer.clientSocket, (uint8_t*)"Cras", 4);
dobinedf9f8d2018-01-21 13:57:02 +010099 LOG_D("fuzz_notifySocketFuzzer: SEND: Crash");
Robert Swiecki251ee7c2019-04-17 21:56:22 +0200100 if (!ret) {
101 LOG_F("fuzz_notifySocketFuzzer");
dobinedf9f8d2018-01-21 13:57:02 +0100102 }
103
104 return true;
105}
106
Robert Swiecki56276192018-01-21 15:43:02 +0100107bool setupSocketFuzzer(honggfuzz_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +0100108 int s, len;
109 socklen_t t;
110 struct sockaddr_un local, remote;
111 char socketPath[512];
dobin040a98e2018-04-14 15:55:23 +0200112 snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid());
dobinedf9f8d2018-01-21 13:57:02 +0100113
114 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
115 perror("socket");
116 return false;
117 }
118
119 local.sun_family = AF_UNIX;
120 strcpy(local.sun_path, socketPath);
121 unlink(local.sun_path);
122 len = strlen(local.sun_path) + sizeof(local.sun_family);
Robert Swiecki56276192018-01-21 15:43:02 +0100123 if (bind(s, (struct sockaddr*)&local, len) == -1) {
dobinedf9f8d2018-01-21 13:57:02 +0100124 perror("bind");
125 return false;
126 }
127
128 if (listen(s, 5) == -1) {
129 perror("listen");
130 return false;
131 }
132
133 printf("Waiting for SocketFuzzer connection on socket: %s\n", socketPath);
134 t = sizeof(remote);
Robert Swiecki251ee7c2019-04-17 21:56:22 +0200135 if ((run->socketFuzzer.clientSocket =
136 TEMP_FAILURE_RETRY(accept(s, (struct sockaddr*)&remote, &t))) == -1) {
dobinedf9f8d2018-01-21 13:57:02 +0100137 perror("accept");
138 return false;
139 }
140
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100141 run->socketFuzzer.serverSocket = s;
dobinedf9f8d2018-01-21 13:57:02 +0100142 printf("A SocketFuzzer client connected. Continuing.\n");
143
144 return true;
145}
146
147void cleanupSocketFuzzer() {
148 char socketPath[512];
dobin040a98e2018-04-14 15:55:23 +0200149 snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid());
dobinedf9f8d2018-01-21 13:57:02 +0100150 unlink(socketPath);
151}