summaryrefslogtreecommitdiff
path: root/libhfuzz/persistent.c
diff options
context:
space:
mode:
authorRobert Swiecki <swiecki@google.com>2016-09-06 14:38:21 +0200
committerRobert Swiecki <swiecki@google.com>2016-09-06 14:38:21 +0200
commit94d54ff5098f44d6713e5e172aca48a418a93dff (patch)
tree80d8aecb4863d6fe26d1b3727f2df0f1d9ce3bdd /libhfuzz/persistent.c
parent3cf9796207121fd59269316957fd5b37506f9d92 (diff)
downloadhonggfuzz-94d54ff5098f44d6713e5e172aca48a418a93dff.tar.gz
Remove -I. from linux and posix builds
Diffstat (limited to 'libhfuzz/persistent.c')
-rw-r--r--libhfuzz/persistent.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/libhfuzz/persistent.c b/libhfuzz/persistent.c
new file mode 100644
index 00000000..f8959f92
--- /dev/null
+++ b/libhfuzz/persistent.c
@@ -0,0 +1,124 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "../common.h"
+
+int LLVMFuzzerTestOneInput(uint8_t * buf, size_t len) __attribute__ ((weak));
+int LLVMFuzzerInitialize(int *argc, char ***argv) __attribute__ ((weak));
+
+static inline ssize_t readFromFd(int fd, uint8_t * buf, size_t len)
+{
+ size_t readSz = 0;
+ while (readSz < len) {
+ ssize_t sz = read(fd, &buf[readSz], len - readSz);
+ if (sz < 0 && errno == EINTR)
+ continue;
+
+ if (sz == 0)
+ break;
+
+ if (sz < 0)
+ return -1;
+
+ readSz += sz;
+ }
+ return (ssize_t) readSz;
+}
+
+static inline bool readFromFdAll(int fd, uint8_t * buf, size_t len)
+{
+ return (readFromFd(fd, buf, len) == (ssize_t) len);
+}
+
+static bool writeToFd(int fd, uint8_t * buf, size_t len)
+{
+ size_t writtenSz = 0;
+ while (writtenSz < len) {
+ ssize_t sz = write(fd, &buf[writtenSz], len - writtenSz);
+ if (sz < 0 && errno == EINTR)
+ continue;
+
+ if (sz < 0)
+ return false;
+
+ writtenSz += sz;
+ }
+ return (writtenSz == len);
+}
+
+static uint8_t buf[_HF_PERF_BITMAP_SIZE_16M] = { 0 };
+
+void HF_ITER(uint8_t ** buf_ptr, size_t * len_ptr)
+{
+ /*
+ * Send the 'done' marker to the parent
+ */
+ static bool initialized = false;
+
+ if (initialized == true) {
+ uint8_t z = 'A';
+ if (writeToFd(_HF_PERSISTENT_FD, &z, sizeof(z)) == false) {
+ fprintf(stderr, "readFromFdAll() failed\n");
+ _exit(1);
+ }
+ }
+ initialized = true;
+
+ uint32_t rlen;
+ if (readFromFdAll(_HF_PERSISTENT_FD, (uint8_t *) & rlen, sizeof(rlen)) == false) {
+ fprintf(stderr, "readFromFdAll(size) failed\n");
+ _exit(1);
+ }
+ size_t len = (size_t) rlen;
+ if (len > _HF_PERF_BITMAP_SIZE_16M) {
+ fprintf(stderr, "len (%zu) > buf_size (%zu)\n", len, (size_t) _HF_PERF_BITMAP_SIZE_16M);
+ _exit(1);
+ }
+
+ if (readFromFdAll(_HF_PERSISTENT_FD, buf, len) == false) {
+ fprintf(stderr, "readFromFdAll(buf) failed\n");
+ _exit(1);
+ }
+
+ *buf_ptr = buf;
+ *len_ptr = len;
+}
+
+/*
+ * Declare it 'weak', so it can be safely linked with regular binaries which
+ * implement their own main()
+ */
+__attribute__ ((weak))
+int main(int argc, char **argv)
+{
+ if (LLVMFuzzerInitialize) {
+ LLVMFuzzerInitialize(&argc, &argv);
+ }
+ if (LLVMFuzzerTestOneInput == NULL) {
+ fprintf(stderr, "Define 'int LLVMFuzzerTestOneInput(uint8_t * buf, size_t len)' in your "
+ "code to make it work\n");
+ exit(1);
+ }
+
+ for (;;) {
+ size_t len;
+ uint8_t *buf;
+
+ HF_ITER(&buf, &len);
+
+ int ret = LLVMFuzzerTestOneInput(buf, len);
+ if (ret != 0) {
+ fprintf(stderr, "LLVMFuzzerTestOneInput() returned '%d' instead of '0'\n", ret);
+ exit(1);
+ }
+ }
+}