git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 07/10] commit-graph: simplify parse_commit_graph() #1

From
SZEDER Gábor via GitGitGadget <gitgitgadget@gmail.com>
Date
Jun 5, 2020, 13:00 UTC
Message-ID
<cd9e033d1b1b4cfb0d5fe485b8b37608c2227ec2.1591362033.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.650.git.1591362032.gitgitgadget@gmail.com>
From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= <szeder.dev@gmail.com>

While we iterate over all entries of the Chunk Lookup table we make sure that we don't attempt to read past the end of the mmap-ed commit-graph file, and check in each iteration that the chunk ID and offset we are about to read is still within the mmap-ed memory region. However, these checks in each iteration are not really necessary, because the number of chunks in the commit-graph file is already known before this loop from the just parsed commit-graph header.

So let's check that the commit-graph file is large enough for all entries in the Chunk Lookup table before we start iterating over those entries, and drop those per-iteration checks. While at it, take into account the size of everything that is necessary to have a valid commit-graph file, i.e. the size of the header, the size of the mandatory OID Fanout chunk, and the size of the signature in the trailer as well.

Note that this necessitates the change of the error message as well, and, consequently, have to update the 'detect incorrect chunk count' test in 't5318-commit-graph.sh' as well.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
 commit-graph.c          | 16 +++++++++-------
 t/t5318-commit-graph.sh |  3 ++-
 2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/commit-graph.c b/commit-graph.c
index 6ed649388d6..9927762f18c 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -272,6 +272,15 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd,
 	graph->data = graph_map;
 	graph->data_len = graph_size;
 
+	if (graph_size < GRAPH_HEADER_SIZE +
+			 (graph->num_chunks + 1) * GRAPH_CHUNKLOOKUP_WIDTH +
+			 GRAPH_FANOUT_SIZE + the_hash_algo->rawsz) {
+		error(_("commit-graph file is too small to hold %u chunks"),
+		      graph->num_chunks);
+		free(graph);
+		return NULL;
+	}
+
 	last_chunk_id = 0;
 	last_chunk_offset = 8;
 	chunk_lookup = data + 8;
@@ -280,13 +289,6 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd,
 		uint64_t chunk_offset;
 		int chunk_repeated = 0;
 
-		if (data + graph_size - chunk_lookup <
-		    GRAPH_CHUNKLOOKUP_WIDTH) {
-			error(_("commit-graph chunk lookup table entry missing; file may be incomplete"));
-			free(graph);
-			return NULL;
-		}
-
 		chunk_id = get_be32(chunk_lookup + 0);
 		chunk_offset = get_be64(chunk_lookup + 4);
 
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index 79e7fbcd40e..1073f9e3cf2 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -574,7 +574,8 @@ test_expect_success 'detect invalid checksum hash' '
 
 test_expect_success 'detect incorrect chunk count' '
 	corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\377" \
-		"chunk lookup table entry missing" $GRAPH_CHUNK_LOOKUP_OFFSET
+		"commit-graph file is too small to hold [0-9]* chunks" \
+		$GRAPH_CHUNK_LOOKUP_OFFSET
 '
 
 test_expect_success 'git fsck (checks commit-graph)' '
-- 
gitgitgadget
Previous: SZEDER Gábor via GitGitGadgetNext: SZEDER Gábor via GitGitGadget
Message 10 of 16 in “Szeder's commit-graph cleanups”
  1. 00/10 Szeder's commit-graph cleanupsDerrick Stolee via GitGitGadget, Jun 5, 2020
  2. 02/10 commit-graph: fix parsing the Chunk Lookup tableSZEDER Gábor via GitGitGadget, Jun 5, 2020
  3. 01/10 tree-walk.c: don't match submodule entries for 'submod/anything'SZEDER Gábor via GitGitGadget, Jun 5, 2020
  4. 03/10 commit-graph-format.txt: all multi-byte numbers are in network byte orderSZEDER Gábor via GitGitGadget, Jun 5, 2020
  5. 04/10 commit-slab: add a function to deep free entries on the slabSZEDER Gábor via GitGitGadget, Jun 5, 2020
  6. René ScharfeJun 18, 2020
  7. Derrick StoleeJun 19, 2020
  8. SZEDER GáborJun 27, 2020
  9. 05/10 diff.h: drop diff_tree_oid() & friends' return valueSZEDER Gábor via GitGitGadget, Jun 5, 2020
  10. 07/10 commit-graph: simplify parse_commit_graph() #1SZEDER Gábor via GitGitGadget, Jun 5, 2020
  11. 06/10 commit-graph: clean up #includesSZEDER Gábor via GitGitGadget, Jun 5, 2020
  12. 08/10 commit-graph: simplify parse_commit_graph() #2SZEDER Gábor via GitGitGadget, Jun 5, 2020
  13. 09/10 commit-graph: simplify write_commit_graph_file() #1SZEDER Gábor via GitGitGadget, Jun 5, 2020
  14. 10/10 commit-graph: simplify write_commit_graph_file() #2SZEDER Gábor via GitGitGadget, Jun 5, 2020
  15. Junio C HamanoJun 8, 2020
  16. Derrick StoleeJun 18, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.