blob: 29783582f78930f3c886ed577fa54776db87d830 [file] [log] [blame]
Robert Swieckic6e51b12019-05-22 16:02:57 +02001#include "socketfuzzer.h"
2
dobinedf9f8d2018-01-21 13:57:02 +01003#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>
Robert Swieckic6e51b12019-05-22 16:02:57 +020016#include <sys/socket.h>
dobinedf9f8d2018-01-21 13:57:02 +010017#include <sys/stat.h>
18#include <sys/time.h>
19#include <sys/types.h>
dobinedf9f8d2018-01-21 13:57:02 +010020#include <sys/un.h>
Robert Swieckic6e51b12019-05-22 16:02:57 +020021#include <time.h>
dobinedf9f8d2018-01-21 13:57:02 +010022#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
dobinedf9f8d2018-01-21 13:57:02 +010031bool 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");
dobinedf9f8d2018-01-21 13:57:02 +010035 }
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
Robert Swiecki56276192018-01-21 15:43:02 +010046bool fuzz_prepareSocketFuzzer(run_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +010047 // Notify fuzzer that he should send teh things
48 LOG_D("fuzz_prepareSocketFuzzer: SEND Fuzz");
Robert Swiecki251ee7c2019-04-17 21:56:22 +020049 return files_sendToSocket(
50 run->global->socketFuzzer.clientSocket, (uint8_t*)"Fuzz", strlen("Fuzz"));
dobinedf9f8d2018-01-21 13:57:02 +010051}
52
53/* Return values:
54 0: error
55 1: okay
56 2: target unresponsive
57*/
Robert Swiecki56276192018-01-21 15:43:02 +010058int fuzz_waitforSocketFuzzer(run_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +010059 ssize_t ret;
Robert Swiecki251ee7c2019-04-17 21:56:22 +020060 uint8_t buf[16];
dobinedf9f8d2018-01-21 13:57:02 +010061
62 // Wait until the external fuzzer did his thing
63 bzero(buf, 16);
Robert Swiecki251ee7c2019-04-17 21:56:22 +020064 ret = files_readFromFd(run->global->socketFuzzer.clientSocket, buf, 4);
dobinedf9f8d2018-01-21 13:57:02 +010065 LOG_D("fuzz_waitforSocketFuzzer: RECV: %s", buf);
66
67 // We dont care what we receive, its just to block here
Robert Swiecki56276192018-01-21 15:43:02 +010068 if (ret < 0) {
Robert Swieckif3ecc0e2018-01-21 15:42:22 +010069 LOG_F("fuzz_waitforSocketFuzzer: received: %zu", ret);
dobinedf9f8d2018-01-21 13:57:02 +010070 }
71
Robert Swiecki56276192018-01-21 15:43:02 +010072 if (memcmp(buf, "okay", 4) == 0) {
dobinedf9f8d2018-01-21 13:57:02 +010073 return 1;
Robert Swiecki56276192018-01-21 15:43:02 +010074 } else if (memcmp(buf, "bad!", 4) == 0) {
dobinedf9f8d2018-01-21 13:57:02 +010075 return 2;
76 }
77
78 return 0;
79}
80
Robert Swiecki56276192018-01-21 15:43:02 +010081bool fuzz_notifySocketFuzzerNewCov(honggfuzz_t* hfuzz) {
dobinedf9f8d2018-01-21 13:57:02 +010082 // Tell the fuzzer that the thing he sent reached new BB's
Robert Swiecki251ee7c2019-04-17 21:56:22 +020083 bool ret = files_sendToSocket(hfuzz->socketFuzzer.clientSocket, (uint8_t*)"New!", 4);
dobinedf9f8d2018-01-21 13:57:02 +010084 LOG_D("fuzz_notifySocketFuzzer: SEND: New!");
Robert Swiecki251ee7c2019-04-17 21:56:22 +020085 if (!ret) {
86 LOG_F("fuzz_notifySocketFuzzer");
dobinedf9f8d2018-01-21 13:57:02 +010087 }
88
89 return true;
90}
91
Robert Swiecki56276192018-01-21 15:43:02 +010092bool fuzz_notifySocketFuzzerCrash(run_t* run) {
Robert Swiecki251ee7c2019-04-17 21:56:22 +020093 bool ret = files_sendToSocket(run->global->socketFuzzer.clientSocket, (uint8_t*)"Cras", 4);
dobinedf9f8d2018-01-21 13:57:02 +010094 LOG_D("fuzz_notifySocketFuzzer: SEND: Crash");
Robert Swiecki251ee7c2019-04-17 21:56:22 +020095 if (!ret) {
96 LOG_F("fuzz_notifySocketFuzzer");
dobinedf9f8d2018-01-21 13:57:02 +010097 }
98
99 return true;
100}
101
Robert Swiecki56276192018-01-21 15:43:02 +0100102bool setupSocketFuzzer(honggfuzz_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +0100103 int s, len;
104 socklen_t t;
105 struct sockaddr_un local, remote;
106 char socketPath[512];
dobin040a98e2018-04-14 15:55:23 +0200107 snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid());
dobinedf9f8d2018-01-21 13:57:02 +0100108
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);
Robert Swiecki56276192018-01-21 15:43:02 +0100118 if (bind(s, (struct sockaddr*)&local, len) == -1) {
dobinedf9f8d2018-01-21 13:57:02 +0100119 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);
Robert Swiecki251ee7c2019-04-17 21:56:22 +0200130 if ((run->socketFuzzer.clientSocket =
131 TEMP_FAILURE_RETRY(accept(s, (struct sockaddr*)&remote, &t))) == -1) {
dobinedf9f8d2018-01-21 13:57:02 +0100132 perror("accept");
133 return false;
134 }
135
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100136 run->socketFuzzer.serverSocket = s;
dobinedf9f8d2018-01-21 13:57:02 +0100137 printf("A SocketFuzzer client connected. Continuing.\n");
138
139 return true;
140}
141
142void cleanupSocketFuzzer() {
143 char socketPath[512];
dobin040a98e2018-04-14 15:55:23 +0200144 snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid());
dobinedf9f8d2018-01-21 13:57:02 +0100145 unlink(socketPath);
146}