blob: c2f293eba32455ad7833148eb93385da9bb02975 [file] [log] [blame]
Robert Swiecki42d932a2016-03-30 19:18:33 +02001#include <errno.h>
Robert Swiecki42d932a2016-03-30 19:18:33 +02002#include <fcntl.h>
3#include <limits.h>
4#include <stdbool.h>
5#include <stdint.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <signal.h>
9#include <sys/stat.h>
10#include <sys/types.h>
11#include <unistd.h>
12
Robert Swiecki61c8dcb2016-03-30 19:27:15 +020013#define HF_FUZZ_FD 1023
Robert Swiecki00afa052016-03-30 19:52:52 +020014#define HF_BUF_SIZE (1024 * 1024 * 16)
Robert Swiecki61c8dcb2016-03-30 19:27:15 +020015
Jaggera72ac9d2016-04-01 23:48:12 +020016static inline ssize_t readFromFd(int fd, uint8_t * buf, size_t len)
Robert Swiecki42d932a2016-03-30 19:18:33 +020017{
Jaggera72ac9d2016-04-01 23:48:12 +020018 size_t readSz = 0;
Robert Swiecki42d932a2016-03-30 19:18:33 +020019 while (readSz < len) {
20 ssize_t sz = read(fd, &buf[readSz], len - readSz);
21 if (sz < 0 && errno == EINTR)
22 continue;
23
Jagger799a4d42016-04-01 23:27:51 +020024 if (sz == 0)
Robert Swiecki42d932a2016-03-30 19:18:33 +020025 break;
26
Jagger799a4d42016-04-01 23:27:51 +020027 if (sz < 0)
28 return -1;
29
Robert Swiecki42d932a2016-03-30 19:18:33 +020030 readSz += sz;
31 }
Jagger35f476e2016-04-02 00:07:26 +020032 return (ssize_t) readSz;
Robert Swiecki42d932a2016-03-30 19:18:33 +020033}
34
Jaggera72ac9d2016-04-01 23:48:12 +020035static inline bool readFromFdAll(int fd, uint8_t * buf, size_t len)
Robert Swiecki42d932a2016-03-30 19:18:33 +020036{
Jagger35f476e2016-04-02 00:07:26 +020037 return (readFromFd(fd, buf, len) == (ssize_t) len);
Robert Swiecki61c8dcb2016-03-30 19:27:15 +020038}
39
Jaggera72ac9d2016-04-01 23:48:12 +020040static bool writeToFd(int fd, uint8_t * buf, size_t len)
Robert Swiecki61c8dcb2016-03-30 19:27:15 +020041{
Jaggera72ac9d2016-04-01 23:48:12 +020042 size_t writtenSz = 0;
Robert Swiecki61c8dcb2016-03-30 19:27:15 +020043 while (writtenSz < len) {
44 ssize_t sz = write(fd, &buf[writtenSz], len - writtenSz);
Robert Swiecki42d932a2016-03-30 19:18:33 +020045 if (sz < 0 && errno == EINTR)
46 continue;
47
48 if (sz < 0)
49 return false;
50
51 writtenSz += sz;
52 }
Robert Swiecki61c8dcb2016-03-30 19:27:15 +020053 return (writtenSz == len);
Robert Swiecki42d932a2016-03-30 19:18:33 +020054}
55
56int LLVMFuzzerTestOneInput(uint8_t * buf, size_t len);
Jagger88c51a12016-04-01 23:19:57 +020057__attribute__ ((weak))
58int LLVMFuzzerInitialize(int *argc, char ***argv);
Robert Swiecki42d932a2016-03-30 19:18:33 +020059
Jaggera72ac9d2016-04-01 23:48:12 +020060int main(int argc, char **argv)
Robert Swiecki42d932a2016-03-30 19:18:33 +020061{
Robert Swiecki39a03732016-04-01 15:43:37 +020062 uint8_t *buf = (uint8_t *) malloc(HF_BUF_SIZE);
Robert Swiecki00afa052016-03-30 19:52:52 +020063 if (buf == NULL) {
64 perror("malloc");
Robert Swieckia93f5b92016-03-30 20:39:34 +020065 _exit(1);
Robert Swiecki00afa052016-03-30 19:52:52 +020066 }
67
Jagger88c51a12016-04-01 23:19:57 +020068 if (LLVMFuzzerInitialize) {
69 LLVMFuzzerInitialize(&argc, &argv);
70 }
71
Robert Swiecki42d932a2016-03-30 19:18:33 +020072 for (;;) {
Jagger04d84822016-04-03 21:54:49 +020073 uint32_t rlen;
Jagger1d743382016-04-02 02:09:41 +020074 if (readFromFdAll(HF_FUZZ_FD, (uint8_t *) & rlen, sizeof(rlen)) == false) {
75 fprintf(stderr, "readFromFdAll(size) failed");
76 _exit(1);
77 }
78 size_t len = (size_t) rlen;
79 if (len > HF_BUF_SIZE) {
80 fprintf(stderr, "len (%zu) > buf_size (%zu)", len, (size_t) HF_BUF_SIZE);
Robert Swieckia93f5b92016-03-30 20:39:34 +020081 _exit(1);
Robert Swiecki42d932a2016-03-30 19:18:33 +020082 }
83
Jagger1d743382016-04-02 02:09:41 +020084 if (readFromFdAll(HF_FUZZ_FD, buf, len) == false) {
85 fprintf(stderr, "readFromFdAll(buf) failed");
Robert Swieckia93f5b92016-03-30 20:39:34 +020086 _exit(1);
Robert Swiecki42d932a2016-03-30 19:18:33 +020087 }
88
Jagger1d743382016-04-02 02:09:41 +020089 int ret = LLVMFuzzerTestOneInput(buf, len);
Robert Swiecki00afa052016-03-30 19:52:52 +020090 if (ret != 0) {
Jagger799a4d42016-04-01 23:27:51 +020091 printf("LLVMFuzzerTestOneInput() returned '%d'", ret);
Robert Swieckia93f5b92016-03-30 20:39:34 +020092 _exit(1);
Robert Swiecki00afa052016-03-30 19:52:52 +020093 }
Robert Swiecki42d932a2016-03-30 19:18:33 +020094
Robert Swiecki3047cd32016-03-31 16:26:01 +020095 /*
96 * Send the 'done' marker to the parent */
Robert Swiecki61c8dcb2016-03-30 19:27:15 +020097 uint8_t z = 'A';
98 if (writeToFd(HF_FUZZ_FD, &z, sizeof(z)) == false) {
Jagger799a4d42016-04-01 23:27:51 +020099 fprintf(stderr, "readFromFdAll() failed");
Robert Swieckia93f5b92016-03-30 20:39:34 +0200100 _exit(1);
Robert Swiecki42d932a2016-03-30 19:18:33 +0200101 }
Robert Swiecki3047cd32016-03-31 16:26:01 +0200102 /*
103 * Inform the parent that we're done, so it can break out of its wait()
Jagger88c51a12016-04-01 23:19:57 +0200104 * sleep cycle
Robert Swiecki3047cd32016-03-31 16:26:01 +0200105 * */
Robert Swiecki42d932a2016-03-30 19:18:33 +0200106 raise(SIGCONT);
107 }
108}