Ad 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 V2:
  * Avoid pointer arithmetic overflow when checking the graph's chunk
    count.
  * Merge the corrupt_graph_and_verify and
    corrupt_and_zero_graph_then_verify test functions.

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 | 15 +++++++--
 6 files changed, 83 insertions(+), 22 deletions(-)
 create mode 100644 fuzz-commit-graph.c

Range-diff against v2:
1:  af45c2337f ! 1:  675d58ecea commit-graph: fix buffer read-overflow
    @@ -22,8 +22,8 @@
     +          uint64_t chunk_offset;
                int chunk_repeated = 0;
      
    -+          if (chunk_lookup + GRAPH_CHUNKLOOKUP_WIDTH >
    -+              data + graph_size) {
    ++          if (data + graph_size - chunk_lookup <
    ++              GRAPH_CHUNKLOOKUP_WIDTH) {
     +                  error(_("chunk lookup table entry missing; graph file 
may be incomplete"));
     +                  free(graph);
     +                  return NULL;
    @@ -40,31 +40,34 @@
      --- a/t/t5318-commit-graph.sh
      +++ b/t/t5318-commit-graph.sh
     @@
    -   test_i18ngrep "$grepstr" err
    - }
    + GRAPH_BYTE_OCTOPUS=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4))
    + GRAPH_BYTE_FOOTER=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4 * $NUM_OCTOPUS_EDGES))
      
    -+
    -+# 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
    +-# usage: corrupt_graph_and_verify <position> <data> <string>
    ++# usage: corrupt_graph_and_verify <position> <data> <string> [<zero_pos>]
    + # Manipulates the commit-graph file at the position
    +-# by inserting the data, then runs 'git commit-graph verify'
    ++# by inserting the data, optionally zeroing the file
    ++# starting at <zero_pos>, then runs 'git commit-graph verify'
    + # and places the output in the file 'err'. Test 'err' for
    + # the given string.
    + corrupt_graph_and_verify() {
    +   pos=$1
    +   data="${2:-\0}"
    +   grepstr=$3
     +  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 &&
    ++  zero_pos=${4:-${orig_size}}
    +   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="$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_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" \
    @@ -73,9 +76,9 @@
                "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 'detect incorrect chunk count' '
    ++  corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\xff" \
    ++          "chunk lookup table entry missing" $GRAPH_CHUNK_LOOKUP_OFFSET
     +'
     +
      test_expect_success 'git fsck (checks commit-graph)' '
2:  7519fc76df = 2:  06a32bfe8b Makefile: correct example fuzz build
-- 
2.20.0.rc2.12.g4c11c11dec

Reply via email to