Home | History | Annotate | Download | only in honggfuzz
      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 
     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 
     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 */
     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 
     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 
    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 
    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 
    161 void cleanupSocketFuzzer() {
    162     char socketPath[512];
    163     snprintf(socketPath, sizeof(socketPath), "/tmp/honggfuzz_socket.%i", getpid());
    164     unlink(socketPath);
    165 }
    166