Merge branch 'js/commit-graph-chunk-table-fix'
authorJunio C Hamano <gitster@pobox.com>
Tue, 5 Feb 2019 22:26:11 +0000 (14:26 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 5 Feb 2019 22:26:11 +0000 (14:26 -0800)
The codepath to read from the commit-graph file attempted to read
past the end of it when the file's table-of-contents was corrupt.

* js/commit-graph-chunk-table-fix:
Makefile: correct example fuzz build
commit-graph: fix buffer read-overflow
commit-graph, fuzz: add fuzzer for commit-graph

1  2 
Makefile
commit-graph.c
diff --cc Makefile
Simple merge
diff --cc commit-graph.c
index 30f1781176612af2a6979635a9b5090d190990cd,359e782deed65ec5478c59b1f439adb90aabf124..18bd2b6df79e51105a17a1d2784608ba0370de36
@@@ -124,10 -147,10 +146,10 @@@ struct commit_graph *parse_commit_graph
        }
  
        hash_version = *(unsigned char*)(data + 5);
 -      if (hash_version != GRAPH_OID_VERSION) {
 +      if (hash_version != oid_version()) {
                error(_("hash version %X does not match version %X"),
 -                    hash_version, GRAPH_OID_VERSION);
 +                    hash_version, oid_version());
-               goto cleanup_fail;
+               return NULL;
        }
  
        graph = alloc_commit_graph();
        last_chunk_offset = 8;
        chunk_lookup = data + 8;
        for (i = 0; i < graph->num_chunks; i++) {
-               uint32_t chunk_id = get_be32(chunk_lookup + 0);
-               uint64_t chunk_offset = get_be64(chunk_lookup + 4);
+               uint32_t chunk_id;
+               uint64_t chunk_offset;
                int chunk_repeated = 0;
  
+               if (data + graph_size - chunk_lookup <
+                   GRAPH_CHUNKLOOKUP_WIDTH) {
+                       error(_("chunk lookup table entry missing; graph file may be incomplete"));
+                       free(graph);
+                       return NULL;
+               }
+               chunk_id = get_be32(chunk_lookup + 0);
+               chunk_offset = get_be64(chunk_lookup + 4);
                chunk_lookup += GRAPH_CHUNKLOOKUP_WIDTH;
  
 -              if (chunk_offset > graph_size - GIT_MAX_RAWSZ) {
 +              if (chunk_offset > graph_size - the_hash_algo->rawsz) {
                        error(_("improper chunk offset %08x%08x"), (uint32_t)(chunk_offset >> 32),
                              (uint32_t)chunk_offset);
-                       goto cleanup_fail;
+                       free(graph);
+                       return NULL;
                }
  
                switch (chunk_id) {