diff options
Diffstat (limited to 'fuzzers')
-rw-r--r-- | fuzzers/download_refs_fuzzer.c | 208 | ||||
-rw-r--r-- | fuzzers/download_refs_fuzzer.cc | 156 |
2 files changed, 208 insertions, 156 deletions
diff --git a/fuzzers/download_refs_fuzzer.c b/fuzzers/download_refs_fuzzer.c new file mode 100644 index 000000000..fd10409d4 --- /dev/null +++ b/fuzzers/download_refs_fuzzer.c @@ -0,0 +1,208 @@ +/* + * libgit2 raw packfile fuzz target. + * + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include <string.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> + +#include "git2.h" +#include "git2/sys/transport.h" + +#define UNUSED(x) (void)(x) + +struct fuzzer_buffer { + const unsigned char *data; + size_t size; +}; + +struct fuzzer_stream { + git_smart_subtransport_stream base; + const unsigned char *readp; + const unsigned char *endp; +}; + +struct fuzzer_subtransport { + git_smart_subtransport base; + git_transport *owner; + struct fuzzer_buffer data; +}; + +static git_repository *repo; + +static int fuzzer_stream_read(git_smart_subtransport_stream *stream, + char *buffer, + size_t buf_size, + size_t *bytes_read) +{ + struct fuzzer_stream *fs = (struct fuzzer_stream *) stream; + size_t avail = fs->endp - fs->readp; + + *bytes_read = (buf_size > avail) ? avail : buf_size; + memcpy(buffer, fs->readp, *bytes_read); + fs->readp += *bytes_read; + + return 0; +} + +static int fuzzer_stream_write(git_smart_subtransport_stream *stream, + const char *buffer, size_t len) +{ + UNUSED(stream); + UNUSED(buffer); + UNUSED(len); + return 0; +} + +static void fuzzer_stream_free(git_smart_subtransport_stream *stream) +{ + free(stream); +} + +static int fuzzer_stream_new( + struct fuzzer_stream **out, + const struct fuzzer_buffer *data) +{ + struct fuzzer_stream *stream = malloc(sizeof(*stream)); + if (!stream) + return -1; + + stream->readp = data->data; + stream->endp = data->data + data->size; + stream->base.read = fuzzer_stream_read; + stream->base.write = fuzzer_stream_write; + stream->base.free = fuzzer_stream_free; + + *out = stream; + + return 0; +} + +static int fuzzer_subtransport_action( + git_smart_subtransport_stream **out, + git_smart_subtransport *transport, + const char *url, + git_smart_service_t action) +{ + struct fuzzer_subtransport *ft = (struct fuzzer_subtransport *) transport; + + UNUSED(url); + UNUSED(action); + + return fuzzer_stream_new((struct fuzzer_stream **) out, &ft->data); +} + +static int fuzzer_subtransport_close(git_smart_subtransport *transport) +{ + UNUSED(transport); + return 0; +} + +static void fuzzer_subtransport_free(git_smart_subtransport *transport) +{ + free(transport); +} + +static int fuzzer_subtransport_new( + struct fuzzer_subtransport **out, + git_transport *owner, + const struct fuzzer_buffer *data) +{ + struct fuzzer_subtransport *sub = malloc(sizeof(*sub)); + if (!sub) + return -1; + + sub->owner = owner; + sub->data.data = data->data; + sub->data.size = data->size; + sub->base.action = fuzzer_subtransport_action; + sub->base.close = fuzzer_subtransport_close; + sub->base.free = fuzzer_subtransport_free; + + *out = sub; + + return 0; +} + +int fuzzer_subtransport_cb( + git_smart_subtransport **out, + git_transport *owner, + void *payload) +{ + struct fuzzer_buffer *buf = (struct fuzzer_buffer *) payload; + struct fuzzer_subtransport *sub; + + if (fuzzer_subtransport_new(&sub, owner, buf) < 0) + return -1; + + *out = &sub->base; + return 0; +} + +int fuzzer_transport_cb(git_transport **out, git_remote *owner, void *param) +{ + git_smart_subtransport_definition def = { + fuzzer_subtransport_cb, + 1, + param + }; + return git_transport_smart(out, owner, &def); +} + +void fuzzer_git_abort(const char *op) +{ + const git_error *err = giterr_last(); + fprintf(stderr, "unexpected libgit error: %s: %s\n", + op, err ? err->message : "<none>"); + abort(); +} + +int LLVMFuzzerInitialize(int *argc, char ***argv) +{ + char tmp[] = "/tmp/git2.XXXXXX"; + + UNUSED(argc); + UNUSED(argv); + + if (git_libgit2_init() < 0) + abort(); + + if (mkdtemp(tmp) != tmp) + abort(); + + if (git_repository_init(&repo, tmp, 1) < 0) + fuzzer_git_abort("git_repository_init"); + + return 0; +} + +int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) +{ + struct fuzzer_buffer buffer = { data, size }; + git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_remote *remote; + + if (git_remote_create_anonymous(&remote, repo, "fuzzer://remote-url") < 0) + fuzzer_git_abort("git_remote_create"); + + callbacks.transport = fuzzer_transport_cb; + callbacks.payload = &buffer; + + if (git_remote_connect(remote, GIT_DIRECTION_FETCH, + &callbacks, NULL, NULL) < 0) + goto out; + + git_remote_download(remote, NULL, NULL); + + out: + git_remote_free(remote); + + return 0; +} diff --git a/fuzzers/download_refs_fuzzer.cc b/fuzzers/download_refs_fuzzer.cc deleted file mode 100644 index 939e67f9a..000000000 --- a/fuzzers/download_refs_fuzzer.cc +++ /dev/null @@ -1,156 +0,0 @@ -#include <git2.h> -#include <git2/sys/transport.h> - -#include <cstring> -#include <cstdlib> -#include <sys/stat.h> - -#include <string> - -struct fuzz_buffer { - const uint8_t *data; - size_t size; -}; - -class fuzzer_stream { -public: - git_smart_subtransport_stream base; - fuzzer_stream(fuzz_buffer data) : readp(data.data), endp(data.data + data.size) { - base.read = fuzzer_stream::read; - base.write = fuzzer_stream::write; - base.free = fuzzer_stream::free; - } - - int do_read(char *buffer, size_t buf_size, size_t *bytes_read) { - size_t avail = endp - readp; - *bytes_read = std::min(buf_size, avail); - memcpy(buffer, readp, *bytes_read); - readp += *bytes_read; - return 0; - } - - static int read(git_smart_subtransport_stream *stream, - char *buffer, - size_t buf_size, - size_t *bytes_read) { - fuzzer_stream *fs = reinterpret_cast<fuzzer_stream*>(stream); - return fs->do_read(buffer, buf_size, bytes_read); - } - - static int write(git_smart_subtransport_stream *stream, - const char *buffer, - size_t len) { - return 0; - } - - static void free(git_smart_subtransport_stream *stream) { - fuzzer_stream *fs = reinterpret_cast<fuzzer_stream*>(stream); - delete fs; - } -private: - const uint8_t *readp; - const uint8_t *endp; -}; - -class fuzzer_subtransport { -public: - git_smart_subtransport base; - fuzzer_subtransport(git_transport *owner, fuzz_buffer data) : owner(owner), data(data) { - base.action = fuzzer_subtransport::action; - base.close = fuzzer_subtransport::close; - base.free = fuzzer_subtransport::free; - } - - int do_action(git_smart_subtransport_stream **out, - git_smart_subtransport *transport, - const char *url, - git_smart_service_t action) { - fuzzer_stream *stream = new fuzzer_stream(this->data); - *out = &stream->base; - return 0; - } - - static int action(git_smart_subtransport_stream **out, - git_smart_subtransport *transport, - const char *url, - git_smart_service_t action) { - fuzzer_subtransport *ft = reinterpret_cast<fuzzer_subtransport*>(transport); - return ft->do_action(out, transport, url, action); - } - - static int close(git_smart_subtransport *transport) { - return 0; - } - - static void free(git_smart_subtransport *transport) { - fuzzer_subtransport *ft = reinterpret_cast<fuzzer_subtransport*>(transport); - delete ft; - } - -private: - git_transport *owner; - fuzz_buffer data; -}; - -int fuzzer_subtransport_cb(git_smart_subtransport **out, - git_transport* owner, - void* param) { - fuzz_buffer *buf = static_cast<fuzz_buffer*>(param); - fuzzer_subtransport *sub = new fuzzer_subtransport(owner, *buf); - - *out = &sub->base; - return 0; -} - -int create_fuzzer_transport(git_transport **out, git_remote *owner, void *param) { - git_smart_subtransport_definition fuzzer_subtransport {fuzzer_subtransport_cb, 1, param}; - return git_transport_smart(out, owner, &fuzzer_subtransport); -} - -void fuzzer_git_abort(const char *op) { - const git_error *err = giterr_last(); - fprintf(stderr, "unexpected libgit error: %s: %s\n", - op, err ? err->message : "<none>"); - abort(); -} - - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - static git_repository *repo = nullptr; - if (repo == nullptr) { - git_libgit2_init(); - char tmp[] = "/tmp/git2.XXXXXX"; - if (mkdtemp(tmp) != tmp) { - abort(); - } - int err = git_repository_init(&repo, tmp, true); - if (err != 0) { - fuzzer_git_abort("git_repository_init"); - } - } - - int err; - git_remote *remote; - err = git_remote_create_anonymous(&remote, repo, "fuzzer://remote-url"); - if (err != 0) { - fuzzer_git_abort("git_remote_create"); - } - - - fuzz_buffer buffer = {data, size}; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; - callbacks.transport = create_fuzzer_transport; - callbacks.payload = &buffer; - - err = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks, nullptr, nullptr); - if (err != 0) { - goto out; - } - - git_remote_download(remote, nullptr, nullptr); - - out: - git_remote_free(remote); - - return 0; -} |