ref: 013e83940de00cb4ee983ec2970946e8df5bc620
parent: 47f5e687278fa34f97363add03a741f01545ecf7
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Wed Mar 6 13:54:11 EST 2024
add a harness target, leave readtags example alone
--- a/examples/readtags.c
+++ b/examples/readtags.c
@@ -62,6 +62,7 @@
int
main(int argc, char **argv)
{
+ int i;
char buf[256];
Aux aux;
Tagctx ctx = {
@@ -79,16 +80,6 @@
return 1;
}
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
- // this block is for fuzzing only, ignore
- while(__AFL_LOOP(10000)){
- if((aux.fd = open(argv[1], O_RDONLY)) >= 0){
- tagsget(&ctx);
- close(aux.fd);
- }
- }
-#else
- int i;
for(i = 1; i < argc; i++){
printf("*** %s\n", argv[i]);
if((aux.fd = open(argv[i], O_RDONLY)) < 0)
@@ -110,6 +101,6 @@
}
printf("\n");
}
-#endif
+
return 0;
}
--- /dev/null
+++ b/harness.c
@@ -1,0 +1,104 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "tags.h"
+
+typedef struct Aux Aux;
+
+struct Aux {
+ const uint8_t *in;
+ int sz;
+ int off;
+};
+
+#define USED(x) (void)x
+
+#ifndef __AFL_FUZZ_TESTCASE_LEN
+ ssize_t fuzz_len;
+ #define __AFL_FUZZ_TESTCASE_LEN fuzz_len
+ unsigned char fuzz_buf[1024000];
+ #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
+ #define __AFL_FUZZ_INIT() void sync(void);
+ #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0)
+ #define __AFL_INIT() sync()
+#endif
+
+__AFL_FUZZ_INIT()
+
+static void
+tag(Tagctx *ctx, int t, const char *k, const char *v, int offset, int size, Tagread f)
+{
+ USED(ctx); USED(t); USED(k); USED(v); USED(offset); USED(size); USED(f);
+}
+
+static void
+toc(Tagctx *ctx, int ms, int offset)
+{
+ USED(ctx); USED(ms); USED(offset);
+}
+
+static int
+ctxread(Tagctx *ctx, void *buf, int cnt)
+{
+ Aux *aux = ctx->aux;
+ int max = aux->sz - aux->off;
+ if(cnt < 0)
+ cnt = 0;
+ else if(cnt > max)
+ cnt = max;
+ memcpy(buf, aux->in, cnt);
+ aux->off += cnt;
+ return cnt;
+}
+
+static int
+ctxseek(Tagctx *ctx, int offset, int whence)
+{
+ Aux *aux = ctx->aux;
+ if(whence == 0)
+ aux->off = offset;
+ else if(whence == 1)
+ aux->off += offset;
+ else if(whence == 2)
+ aux->off = aux->sz + offset;
+ if(aux->off < 0)
+ aux->off = 0;
+ else if(aux->off > aux->sz)
+ aux->off = aux->sz;
+ return aux->off;
+}
+
+int
+main(int argc, char **argv)
+{
+ char buf[256];
+ Aux aux;
+ Tagctx ctx = {
+ .read = ctxread,
+ .seek = ctxseek,
+ .tag = tag,
+ .toc = toc,
+ .buf = buf,
+ .bufsz = sizeof(buf),
+ .aux = &aux,
+ };
+
+ USED(argc); USED(argv);
+
+ #ifdef __AFL_HAVE_MANUAL_CONTROL
+ __AFL_INIT();
+ #endif
+
+ aux.in = __AFL_FUZZ_TESTCASE_BUF;
+ while(__AFL_LOOP(10000)){
+ aux.sz = __AFL_FUZZ_TESTCASE_LEN;
+ if(aux.sz < 8)
+ continue;
+ aux.off = 0;
+ tagsget(&ctx);
+ }
+
+ return 0;
+}
--- a/meson.build
+++ b/meson.build
@@ -47,6 +47,13 @@
'examples/readtags.c',
]
+
+if(get_option('fuzz'))
+ if(cc.has_argument('-Wno-gnu-statement-expression-from-macro-expansion'))
+ add_project_arguments('-Wno-gnu-statement-expression-from-macro-expansion', language: 'c')
+ endif
+endif
+
lib = static_library(
'tags',
sources: src_lib,
@@ -67,3 +74,12 @@
dependencies: [ libtags ],
install: false,
)
+
+if(get_option('fuzz'))
+ executable(
+ 'harness',
+ sources: [ 'harness.c' ],
+ dependencies: [ libtags ],
+ install: false,
+ )
+endif
--- /dev/null
+++ b/meson.options
@@ -1,0 +1,1 @@
+option('fuzz', type: 'boolean', value: false, description: 'Build fuzzing target')