From: "Brian Tracy via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Josh Steadmon <steadmon@google.com>,
Arthur Chan <arthur.chan@adalogics.com>,
Brian Tracy <brian.tracy33@gmail.com>,
Brian C Tracy <brian.tracy33@gmail.com>
Subject: [PATCH v2] fuzz: add fuzzer for config parsing
Date: Fri, 15 Mar 2024 05:47:31 +0000 [thread overview]
Message-ID: <pull.1692.v2.git.1710481652130.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1692.git.1710398478718.gitgitgadget@gmail.com>
From: Brian C Tracy <brian.tracy33@gmail.com>
Add a new fuzz target that exercises the parsing of git configs.
The existing git_config_from_mem function is a perfect entry point
for fuzzing as it exercises the same code paths as the rest of the
config parsing functions and offers an easily fuzzable interface.
Config parsing is a useful thing to fuzz because it operates on user
controlled data and is a central component of many git operations.
Signed-off-by: Brian C Tracy <brian.tracy33@gmail.com>
---
fuzz: add fuzzer for config parsing
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1692%2Fbriantracy%2Fconfig-fuzzer-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1692/briantracy/config-fuzzer-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/1692
Range-diff vs v1:
1: a43a2e3a07c ! 1: be6aa5efb1c fuzz: add fuzzer for config parsing
@@ Commit message
Signed-off-by: Brian C Tracy <brian.tracy33@gmail.com>
## Makefile ##
-@@ Makefile: FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o
+@@ Makefile: ETAGS_TARGET = TAGS
+ # runs in the future.
+ FUZZ_OBJS += oss-fuzz/dummy-cmd-main.o
+ FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o
++FUZZ_OBJS += oss-fuzz/fuzz-config.o
FUZZ_OBJS += oss-fuzz/fuzz-date.o
FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o
FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o
-+FUZZ_OBJS += oss-fuzz/fuzz-config.o
- .PHONY: fuzz-objs
- fuzz-objs: $(FUZZ_OBJS)
-
## ci/run-build-and-minimal-fuzzers.sh ##
@@ ci/run-build-and-minimal-fuzzers.sh: group "Build fuzzers" make \
@@ ci/run-build-and-minimal-fuzzers.sh: group "Build fuzzers" make \
fuzz-all
-for fuzzer in commit-graph date pack-headers pack-idx ; do
-+for fuzzer in commit-graph date pack-headers pack-idx config ; do
++for fuzzer in commit-graph config date pack-headers pack-idx ; do
begin_group "fuzz-$fuzzer"
./oss-fuzz/fuzz-$fuzzer -verbosity=0 -runs=1 || exit 1
end_group "fuzz-$fuzzer"
## oss-fuzz/.gitignore ##
-@@ oss-fuzz/.gitignore: fuzz-commit-graph
+@@
+ fuzz-commit-graph
++fuzz-config
fuzz-date
fuzz-pack-headers
fuzz-pack-idx
-+fuzz-config
## oss-fuzz/fuzz-config.c (new) ##
@@
+#include "git-compat-util.h"
+#include "config.h"
+
-+#include <stdio.h>
-+#include <string.h>
-+
+int LLVMFuzzerTestOneInput(const uint8_t *, size_t);
+static int config_parser_callback(const char *, const char *,
+ const struct config_context *, void *);
@@ oss-fuzz/fuzz-config.c (new)
+ 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. Ensure a return of 0 to indicate
-+ * success so the parsing continues. */
-+ int c = strlen(key);
++ /*
++ * 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 < 0;
++ 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,
Makefile | 1 +
ci/run-build-and-minimal-fuzzers.sh | 2 +-
oss-fuzz/.gitignore | 1 +
oss-fuzz/fuzz-config.c | 33 +++++++++++++++++++++++++++++
4 files changed, 36 insertions(+), 1 deletion(-)
create mode 100644 oss-fuzz/fuzz-config.c
diff --git a/Makefile b/Makefile
index 4e255c81f22..af32028b18f 100644
--- a/Makefile
+++ b/Makefile
@@ -757,6 +757,7 @@ ETAGS_TARGET = TAGS
# runs in the future.
FUZZ_OBJS += oss-fuzz/dummy-cmd-main.o
FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o
+FUZZ_OBJS += oss-fuzz/fuzz-config.o
FUZZ_OBJS += oss-fuzz/fuzz-date.o
FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o
FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o
diff --git a/ci/run-build-and-minimal-fuzzers.sh b/ci/run-build-and-minimal-fuzzers.sh
index 8ba486f6598..a51076d18df 100755
--- a/ci/run-build-and-minimal-fuzzers.sh
+++ b/ci/run-build-and-minimal-fuzzers.sh
@@ -12,7 +12,7 @@ group "Build fuzzers" make \
LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \
fuzz-all
-for fuzzer in commit-graph date pack-headers pack-idx ; do
+for fuzzer in commit-graph config date pack-headers pack-idx ; do
begin_group "fuzz-$fuzzer"
./oss-fuzz/fuzz-$fuzzer -verbosity=0 -runs=1 || exit 1
end_group "fuzz-$fuzzer"
diff --git a/oss-fuzz/.gitignore b/oss-fuzz/.gitignore
index 5b954088254..a877c11f42b 100644
--- a/oss-fuzz/.gitignore
+++ b/oss-fuzz/.gitignore
@@ -1,4 +1,5 @@
fuzz-commit-graph
+fuzz-config
fuzz-date
fuzz-pack-headers
fuzz-pack-idx
diff --git a/oss-fuzz/fuzz-config.c b/oss-fuzz/fuzz-config.c
new file mode 100644
index 00000000000..94027f5b97e
--- /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;
+}
base-commit: 945115026aa63df4ab849ab14a04da31623abece
--
gitgitgadget
prev parent reply other threads:[~2024-03-15 5:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-14 6:41 [PATCH] fuzz: add fuzzer for config parsing Brian Tracy via GitGitGadget
2024-03-14 16:52 ` Junio C Hamano
2024-03-15 5:47 ` Brian Tracy via GitGitGadget [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.1692.v2.git.1710481652130.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=arthur.chan@adalogics.com \
--cc=brian.tracy33@gmail.com \
--cc=git@vger.kernel.org \
--cc=steadmon@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.