From: Josh Steadmon <steadmon@google.com>
To: git@vger.kernel.org, gitster@pobox.com, stolee@gmail.com,
avarab@gmail.com
Subject: [PATCH v2 0/3] Add commit-graph fuzzer and fix buffer overflow
Date: Thu, 6 Dec 2018 12:20:52 -0800 [thread overview]
Message-ID: <cover.1544127439.git.steadmon@google.com> (raw)
In-Reply-To: <cover.1544048946.git.steadmon@google.com>
Add a new fuzz test for the commit graph and fix a buffer read-overflow
that it discovered. Additionally, fix the Makefile instructions for
building fuzzers.
Changes since V1:
* Moved the parse_commit_graph() declaration to the header file, since
we don't mind if others use it.
* Moved some unnecessary comments into commit messages.
* Fixed some style issues.
* Added a test case for detecting commit graphs with missing chunk
lookup entries.
* Ævar's comments on the Makefile made me realize the fuzzer build
instructions were using the wrong variable. Added a new commit to
fix this.
Josh Steadmon (3):
commit-graph, fuzz: Add fuzzer for commit-graph
commit-graph: fix buffer read-overflow
Makefile: correct example fuzz build
.gitignore | 1 +
Makefile | 3 +-
commit-graph.c | 67 +++++++++++++++++++++++++++++------------
commit-graph.h | 3 ++
fuzz-commit-graph.c | 16 ++++++++++
t/t5318-commit-graph.sh | 28 +++++++++++++++++
6 files changed, 98 insertions(+), 20 deletions(-)
create mode 100644 fuzz-commit-graph.c
Range-diff against v1:
1: 53e62baaa8 ! 1: 0b57ecbe1b commit-graph, fuzz: Add fuzzer for commit-graph
@@ -4,7 +4,9 @@
Breaks load_commit_graph_one() into a new function,
parse_commit_graph(). The latter function operates on arbitrary buffers,
- which makes it suitable as a fuzzing target.
+ which makes it suitable as a fuzzing target. Since parse_commit_graph()
+ is only called by load_commit_graph_one() (and the fuzzer described
+ below), we omit error messages that would be duplicated by the caller.
Adds fuzz-commit-graph.c, which provides a fuzzing entry point
compatible with libFuzzer (and possibly other fuzzing engines).
@@ -35,17 +37,6 @@
diff --git a/commit-graph.c b/commit-graph.c
--- a/commit-graph.c
+++ b/commit-graph.c
-@@
- #define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * GRAPH_CHUNKLOOKUP_WIDTH \
- + GRAPH_FANOUT_SIZE + GRAPH_OID_LEN)
-
-+struct commit_graph *parse_commit_graph(void *graph_map, int fd,
-+ size_t graph_size);
-+
-+
- char *get_commit_graph_filename(const char *obj_dir)
- {
- return xstrfmt("%s/info/commit-graph", obj_dir);
@@
struct commit_graph *load_commit_graph_one(const char *graph_file)
{
@@ -70,7 +61,7 @@
graph_map = xmmap(NULL, graph_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ ret = parse_commit_graph(graph_map, fd, graph_size);
+
-+ if (ret == NULL) {
++ if (!ret) {
+ munmap(graph_map, graph_size);
+ close(fd);
+ exit(1);
@@ -79,10 +70,6 @@
+ return ret;
+}
+
-+/*
-+ * This function is intended to be used only from load_commit_graph_one() or in
-+ * fuzz tests.
-+ */
+struct commit_graph *parse_commit_graph(void *graph_map, int fd,
+ size_t graph_size)
+{
@@ -94,11 +81,9 @@
+ uint32_t graph_signature;
+ unsigned char graph_version, hash_version;
+
-+ /*
-+ * This should already be checked in load_commit_graph_one, but we still
-+ * need a check here for when we're calling parse_commit_graph directly
-+ * from fuzz tests. We can omit the error message in that case.
-+ */
++ if (!graph_map)
++ return NULL;
++
+ if (graph_size < GRAPH_MIN_SIZE)
+ return NULL;
+
@@ -162,12 +147,25 @@
static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
+ diff --git a/commit-graph.h b/commit-graph.h
+ --- a/commit-graph.h
+ +++ b/commit-graph.h
+@@
+
+ struct commit_graph *load_commit_graph_one(const char *graph_file);
+
++struct commit_graph *parse_commit_graph(void *graph_map, int fd,
++ size_t graph_size);
++
+ /*
+ * Return 1 if and only if the repository has a commit-graph
+ * file and generation numbers are computed in that file.
+
diff --git a/fuzz-commit-graph.c b/fuzz-commit-graph.c
new file mode 100644
--- /dev/null
+++ b/fuzz-commit-graph.c
@@
-+#include "object-store.h"
+#include "commit-graph.h"
+
+struct commit_graph *parse_commit_graph(void *graph_map, int fd,
@@ -179,9 +177,8 @@
+{
+ struct commit_graph *g;
+
-+ g = parse_commit_graph((void *) data, -1, size);
-+ if (g)
-+ free(g);
++ g = parse_commit_graph((void *)data, -1, size);
++ free(g);
+
+ return 0;
+}
2: ad2e761f44 ! 2: af45c2337f commit-graph: fix buffer read-overflow
@@ -22,7 +22,8 @@
+ uint64_t chunk_offset;
int chunk_repeated = 0;
-+ if (chunk_lookup + GRAPH_CHUNKLOOKUP_WIDTH > data + graph_size) {
++ if (chunk_lookup + GRAPH_CHUNKLOOKUP_WIDTH >
++ data + graph_size) {
+ error(_("chunk lookup table entry missing; graph file may be incomplete"));
+ free(graph);
+ return NULL;
@@ -34,3 +35,49 @@
chunk_lookup += GRAPH_CHUNKLOOKUP_WIDTH;
if (chunk_offset > graph_size - GIT_MAX_RAWSZ) {
+
+ diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
+ --- a/t/t5318-commit-graph.sh
+ +++ b/t/t5318-commit-graph.sh
+@@
+ test_i18ngrep "$grepstr" err
+ }
+
++
++# usage: corrupt_and_zero_graph_then_verify <corrupt_position> <data> <zero_position> <string>
++# Manipulates the commit-graph file at <corrupt_position> by inserting the data,
++# then zeros the file starting at <zero_position>. Finally, runs
++# 'git commit-graph verify' and places the output in the file 'err'. Tests 'err'
++# for the given string.
++corrupt_and_zero_graph_then_verify() {
++ corrupt_pos=$1
++ data="${2:-\0}"
++ zero_pos=$3
++ grepstr=$4
++ orig_size=$(stat --format=%s $objdir/info/commit-graph)
++ cd "$TRASH_DIRECTORY/full" &&
++ test_when_finished mv commit-graph-backup $objdir/info/commit-graph &&
++ cp $objdir/info/commit-graph commit-graph-backup &&
++ printf "$data" | dd of="$objdir/info/commit-graph" bs=1 seek="$corrupt_pos" conv=notrunc &&
++ truncate --size=$zero_pos $objdir/info/commit-graph &&
++ truncate --size=$orig_size $objdir/info/commit-graph &&
++ test_must_fail git commit-graph verify 2>test_err &&
++ grep -v "^+" test_err >err &&
++ test_i18ngrep "$grepstr" err
++}
++
+ test_expect_success 'detect bad signature' '
+ corrupt_graph_and_verify 0 "\0" \
+ "graph signature"
+@@
+ "incorrect checksum"
+ '
+
++test_expect_success 'detect truncated graph' '
++ corrupt_and_zero_graph_then_verify $GRAPH_BYTE_CHUNK_COUNT "\xff" \
++ $GRAPH_CHUNK_LOOKUP_OFFSET "chunk lookup table entry missing"
++'
++
+ test_expect_success 'git fsck (checks commit-graph)' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git fsck &&
-: ---------- > 3: 7519fc76df Makefile: correct example fuzz build
--
2.20.0.rc2.10.g7519fc76df
next prev parent reply other threads:[~2018-12-06 20:21 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-05 22:32 [PATCH 0/2] Add commit-graph fuzzer and fix buffer overflow Josh Steadmon
2018-12-05 22:32 ` [PATCH 1/2] commit-graph, fuzz: Add fuzzer for commit-graph Josh Steadmon
2018-12-05 22:48 ` Ævar Arnfjörð Bjarmason
2018-12-06 1:00 ` Josh Steadmon
2018-12-06 1:32 ` Junio C Hamano
2018-12-06 1:41 ` Junio C Hamano
2018-12-06 4:47 ` Junio C Hamano
2018-12-05 22:32 ` [PATCH 2/2] commit-graph: fix buffer read-overflow Josh Steadmon
2018-12-06 13:11 ` Derrick Stolee
2018-12-06 20:20 ` Josh Steadmon [this message]
2018-12-06 20:20 ` [PATCH v2 1/3] commit-graph, fuzz: Add fuzzer for commit-graph Josh Steadmon
2018-12-06 20:20 ` [PATCH v2 2/3] commit-graph: fix buffer read-overflow Josh Steadmon
2018-12-07 9:07 ` Jeff King
2018-12-07 13:33 ` Derrick Stolee
2018-12-06 20:20 ` [PATCH v2 3/3] Makefile: correct example fuzz build Josh Steadmon
2018-12-07 22:27 ` [PATCH v3 0/3] Add commit-graph fuzzer and fix buffer overflow Josh Steadmon
2018-12-07 22:27 ` [PATCH v3 1/3] commit-graph, fuzz: Add fuzzer for commit-graph Josh Steadmon
2018-12-07 22:27 ` [PATCH v3 2/3] commit-graph: fix buffer read-overflow Josh Steadmon
2018-12-09 4:01 ` Junio C Hamano
2018-12-10 4:28 ` SZEDER Gábor
2018-12-10 21:58 ` Josh Steadmon
2018-12-10 21:56 ` Josh Steadmon
2018-12-11 9:50 ` Jeff King
2018-12-07 22:27 ` [PATCH v3 3/3] Makefile: correct example fuzz build Josh Steadmon
2018-12-13 19:43 ` [PATCH v4 0/3] Add commit-graph fuzzer and fix buffer overflow Josh Steadmon
2018-12-13 19:43 ` [PATCH v4 1/3] commit-graph, fuzz: Add fuzzer for commit-graph Josh Steadmon
2018-12-13 19:43 ` [PATCH v4 2/3] commit-graph: fix buffer read-overflow Josh Steadmon
2019-01-12 10:57 ` SZEDER Gábor
2019-01-15 19:58 ` Josh Steadmon
2018-12-13 19:43 ` [PATCH v4 3/3] Makefile: correct example fuzz build Josh Steadmon
2018-12-18 17:35 ` [PATCH v4 0/3] Add commit-graph fuzzer and fix buffer overflow Jeff King
2018-12-18 21:05 ` Josh Steadmon
2018-12-19 15:51 ` Jeff King
2018-12-20 19:35 ` Johannes Schindelin
2018-12-20 20:11 ` Jeff King
2018-12-26 22:29 ` Junio C Hamano
2019-01-15 19:59 ` [PATCH v5 " Josh Steadmon
2019-01-15 19:59 ` [PATCH v5 1/3] commit-graph, fuzz: Add fuzzer for commit-graph Josh Steadmon
2019-01-15 20:33 ` Junio C Hamano
2019-01-15 19:59 ` [PATCH v5 2/3] commit-graph: fix buffer read-overflow Josh Steadmon
2019-01-15 19:59 ` [PATCH v5 3/3] Makefile: correct example fuzz build Josh Steadmon
2019-01-15 20:39 ` Junio C Hamano
2019-01-15 21:59 ` Josh Steadmon
2019-01-15 22:34 ` Junio C Hamano
2019-01-15 22:25 ` [PATCH v6 0/3] Add commit-graph fuzzer and fix buffer overflow Josh Steadmon
2019-01-15 22:25 ` [PATCH v6 1/3] commit-graph, fuzz: Add fuzzer for commit-graph Josh Steadmon
2019-01-15 22:25 ` [PATCH v6 2/3] commit-graph: fix buffer read-overflow Josh Steadmon
2019-02-20 14:55 ` Ævar Arnfjörð Bjarmason
2019-02-20 16:50 ` SZEDER Gábor
2019-01-15 22:25 ` [PATCH v6 3/3] Makefile: correct example fuzz build Josh Steadmon
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=cover.1544127439.git.steadmon@google.com \
--to=steadmon@google.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=stolee@gmail.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.