summaryrefslogtreecommitdiff
path: root/oss-fuzz
diff options
context:
space:
mode:
Diffstat (limited to 'oss-fuzz')
-rw-r--r--oss-fuzz/.gitignore8
-rw-r--r--oss-fuzz/dummy-cmd-main.c14
-rw-r--r--oss-fuzz/fuzz-commit-graph.c32
-rw-r--r--oss-fuzz/fuzz-config.c33
-rw-r--r--oss-fuzz/fuzz-credential-from-url-gently.c32
-rw-r--r--oss-fuzz/fuzz-date.c49
-rw-r--r--oss-fuzz/fuzz-pack-headers.c15
-rw-r--r--oss-fuzz/fuzz-pack-idx.c14
-rw-r--r--oss-fuzz/fuzz-parse-attr-line.c41
-rw-r--r--oss-fuzz/fuzz-url-decode-mem.c43
-rw-r--r--oss-fuzz/meson.build20
11 files changed, 301 insertions, 0 deletions
diff --git a/oss-fuzz/.gitignore b/oss-fuzz/.gitignore
new file mode 100644
index 0000000000..f2d74de457
--- /dev/null
+++ b/oss-fuzz/.gitignore
@@ -0,0 +1,8 @@
+fuzz-commit-graph
+fuzz-config
+fuzz-credential-from-url-gently
+fuzz-date
+fuzz-pack-headers
+fuzz-pack-idx
+fuzz-parse-attr-line
+fuzz-url-decode-mem
diff --git a/oss-fuzz/dummy-cmd-main.c b/oss-fuzz/dummy-cmd-main.c
new file mode 100644
index 0000000000..8ef776d06f
--- /dev/null
+++ b/oss-fuzz/dummy-cmd-main.c
@@ -0,0 +1,14 @@
+#include "git-compat-util.h"
+
+/*
+ * When linking the fuzzers, we link against common-main.o to pick up some
+ * symbols. However, even though we ignore common-main:main(), we still need to
+ * provide all the symbols it references. In the fuzzers' case, we need to
+ * provide a dummy cmd_main() for the linker to be happy. It will never be
+ * executed.
+ */
+
+int cmd_main(int argc UNUSED, const char **argv UNUSED) {
+ BUG("We should not execute cmd_main() from a fuzz target");
+ return 1;
+}
diff --git a/oss-fuzz/fuzz-commit-graph.c b/oss-fuzz/fuzz-commit-graph.c
new file mode 100644
index 0000000000..fbb77fec19
--- /dev/null
+++ b/oss-fuzz/fuzz-commit-graph.c
@@ -0,0 +1,32 @@
+#define USE_THE_REPOSITORY_VARIABLE
+
+#include "git-compat-util.h"
+#include "commit-graph.h"
+#include "repository.h"
+
+struct commit_graph *parse_commit_graph(struct repo_settings *s,
+ void *graph_map, size_t graph_size);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ struct commit_graph *g;
+
+ initialize_repository(the_repository);
+
+ /*
+ * Initialize the_repository with commit-graph settings that would
+ * normally be read from the repository's gitdir. We want to avoid
+ * touching the disk to keep the individual fuzz-test cases as fast as
+ * possible.
+ */
+ repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+ the_repository->settings.commit_graph_generation_version = 2;
+ the_repository->settings.commit_graph_changed_paths_version = 1;
+ g = parse_commit_graph(&the_repository->settings, (void *)data, size);
+ repo_clear(the_repository);
+ free_commit_graph(g);
+
+ return 0;
+}
diff --git a/oss-fuzz/fuzz-config.c b/oss-fuzz/fuzz-config.c
new file mode 100644
index 0000000000..94027f5b97
--- /dev/null
+++ b/oss-fuzz/fuzz-config.c
@@ -0,0 +1,33 @@
+#include "git-compat-util.h"
+#include "config.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *, size_t);
+static int config_parser_callback(const char *, const char *,
+ const struct config_context *, void *);
+
+static int config_parser_callback(const char *key, const char *value,
+ const struct config_context *ctx UNUSED,
+ void *data UNUSED)
+{
+ /*
+ * Visit every byte of memory we are given to make sure the parser
+ * gave it to us appropriately. We need to unconditionally return 0,
+ * but we also want to prevent the strlen from being optimized away.
+ */
+ size_t c = strlen(key);
+
+ if (value)
+ c += strlen(value);
+ return c == SIZE_MAX;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, const size_t size)
+{
+ struct config_options config_opts = { 0 };
+
+ config_opts.error_action = CONFIG_ERROR_SILENT;
+ git_config_from_mem(config_parser_callback, CONFIG_ORIGIN_BLOB,
+ "fuzztest-config", (const char *)data, size, NULL,
+ CONFIG_SCOPE_UNKNOWN, &config_opts);
+ return 0;
+}
diff --git a/oss-fuzz/fuzz-credential-from-url-gently.c b/oss-fuzz/fuzz-credential-from-url-gently.c
new file mode 100644
index 0000000000..c872f9ad2d
--- /dev/null
+++ b/oss-fuzz/fuzz-credential-from-url-gently.c
@@ -0,0 +1,32 @@
+#include "git-compat-util.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include "credential.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ struct credential c;
+ char *buf;
+
+ buf = malloc(size + 1);
+ if (!buf)
+ return 0;
+
+ memcpy(buf, data, size);
+ buf[size] = 0;
+
+ // start fuzzing
+ credential_init(&c);
+ credential_from_url_gently(&c, buf, 1);
+
+ // cleanup
+ credential_clear(&c);
+ free(buf);
+
+ return 0;
+}
diff --git a/oss-fuzz/fuzz-date.c b/oss-fuzz/fuzz-date.c
new file mode 100644
index 0000000000..9619dae40e
--- /dev/null
+++ b/oss-fuzz/fuzz-date.c
@@ -0,0 +1,49 @@
+#include "git-compat-util.h"
+#include "date.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ int local;
+ int num;
+ char *str;
+ int16_t tz;
+ timestamp_t ts;
+ enum date_mode_type dmtype;
+ struct date_mode dm;
+
+ if (size <= 4)
+ /*
+ * we use the first byte to fuzz dmtype and the
+ * second byte to fuzz local, then the next two
+ * bytes to fuzz tz offset. The remainder
+ * (at least one byte) is fed as input to
+ * approxidate_careful().
+ */
+ return 0;
+
+ local = !!(*data++ & 0x10);
+ num = *data++ % DATE_UNIX;
+ if (num >= DATE_STRFTIME)
+ num++;
+ dmtype = (enum date_mode_type)num;
+ size -= 2;
+
+ tz = *data++;
+ tz = (tz << 8) | *data++;
+ size -= 2;
+
+ str = xmemdupz(data, size);
+
+ ts = approxidate_careful(str, &num);
+ free(str);
+
+ dm = date_mode_from_type(dmtype);
+ dm.local = local;
+ show_date(ts, (int)tz, dm);
+
+ date_mode_release(&dm);
+
+ return 0;
+}
diff --git a/oss-fuzz/fuzz-pack-headers.c b/oss-fuzz/fuzz-pack-headers.c
new file mode 100644
index 0000000000..150c0f5fa2
--- /dev/null
+++ b/oss-fuzz/fuzz-pack-headers.c
@@ -0,0 +1,15 @@
+#include "git-compat-util.h"
+#include "packfile.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ enum object_type type;
+ unsigned long len;
+
+ unpack_object_header_buffer((const unsigned char *)data,
+ (unsigned long)size, &type, &len);
+
+ return 0;
+}
diff --git a/oss-fuzz/fuzz-pack-idx.c b/oss-fuzz/fuzz-pack-idx.c
new file mode 100644
index 0000000000..d2a92f34d9
--- /dev/null
+++ b/oss-fuzz/fuzz-pack-idx.c
@@ -0,0 +1,14 @@
+#include "git-compat-util.h"
+#include "odb.h"
+#include "packfile.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ struct packed_git p;
+
+ load_idx("fuzz-input", GIT_SHA1_RAWSZ, (void *)data, size, &p);
+
+ return 0;
+}
diff --git a/oss-fuzz/fuzz-parse-attr-line.c b/oss-fuzz/fuzz-parse-attr-line.c
new file mode 100644
index 0000000000..315198505c
--- /dev/null
+++ b/oss-fuzz/fuzz-parse-attr-line.c
@@ -0,0 +1,41 @@
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
+#include "git-compat-util.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "attr.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ struct match_attr *res;
+ char *buf;
+
+ buf = malloc(size + 1);
+ if (!buf)
+ return 0;
+
+ memcpy(buf, data, size);
+ buf[size] = 0;
+
+ res = parse_attr_line(buf, "dummy", 0, 0);
+
+ if (res) {
+ size_t j;
+ for (j = 0; j < res->num_attr; j++) {
+ const char *setto = res->state[j].setto;
+ if (ATTR_TRUE(setto) || ATTR_FALSE(setto) ||
+ ATTR_UNSET(setto))
+ ;
+ else
+ free((char *)setto);
+ }
+ free(res);
+ }
+ free(buf);
+
+ return 0;
+}
diff --git a/oss-fuzz/fuzz-url-decode-mem.c b/oss-fuzz/fuzz-url-decode-mem.c
new file mode 100644
index 0000000000..2342aa993b
--- /dev/null
+++ b/oss-fuzz/fuzz-url-decode-mem.c
@@ -0,0 +1,43 @@
+#include "git-compat-util.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include "url.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ char *buf;
+ char *r;
+ const char *pbuf;
+
+ buf = malloc(size + 1);
+ if (!buf)
+ return 0;
+
+ memcpy(buf, data, size);
+ buf[size] = 0;
+
+ // start fuzzing
+ r = url_decode(buf);
+ free(r);
+
+ r = url_percent_decode(buf);
+ free(r);
+
+ pbuf = (const char*) buf;
+ r = url_decode_parameter_name(&pbuf);
+ free(r);
+
+ pbuf = (const char*) buf;
+ r = url_decode_parameter_value(&pbuf);
+ free(r);
+
+ // cleanup
+ free(buf);
+
+ return 0;
+}
diff --git a/oss-fuzz/meson.build b/oss-fuzz/meson.build
new file mode 100644
index 0000000000..878afd8426
--- /dev/null
+++ b/oss-fuzz/meson.build
@@ -0,0 +1,20 @@
+fuzz_programs = [
+ 'fuzz-commit-graph.c',
+ 'fuzz-config.c',
+ 'fuzz-credential-from-url-gently.c',
+ 'fuzz-date.c',
+ 'fuzz-pack-headers.c',
+ 'fuzz-pack-idx.c',
+ 'fuzz-parse-attr-line.c',
+ 'fuzz-url-decode-mem.c',
+]
+
+foreach fuzz_program : fuzz_programs
+ executable(fs.stem(fuzz_program),
+ sources: [
+ 'dummy-cmd-main.c',
+ fuzz_program,
+ ],
+ dependencies: [libgit_commonmain],
+ )
+endforeach