commit-graph.c: prevent overflow in `write_commit_graph_file()`

When writing a commit-graph, we use the chunk-format API to write out each individual chunk of the commit-graph. Each chunk of the commit-graph is tracked via a call to `add_chunk()`, along with the expected size of that chunk. Similar to an earlier commit which handled the identical issue in the MIDX machinery, guard against overflow when dealing with a commit-graph with a large number of entries to avoid corrupting the contents of the commit-graph itself. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed Jul 12, 2023 at 19:37 UTC 48f3f8cf37043f69e9834d38e2439abfde280964
1 file changed +10 -10
commit-graph.c
+10 -10
@@ -1953,35 +1953,35 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
1953
1954 add_chunk(cf, GRAPH_CHUNKID_OIDFANOUT, GRAPH_FANOUT_SIZE,
1955 write_graph_chunk_fanout);
1956 - add_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, hashsz * ctx->commits.nr,
1956 + add_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, st_mult(hashsz, ctx->commits.nr),
1957 write_graph_chunk_oids);
1958 - add_chunk(cf, GRAPH_CHUNKID_DATA, (hashsz + 16) * ctx->commits.nr,
1958 + add_chunk(cf, GRAPH_CHUNKID_DATA, st_mult(hashsz + 16, ctx->commits.nr),
1959 write_graph_chunk_data);
1960
1961 if (ctx->write_generation_data)
1962 add_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA,
1963 - sizeof(uint32_t) * ctx->commits.nr,
1963 + st_mult(sizeof(uint32_t), ctx->commits.nr),
1964 write_graph_chunk_generation_data);
1965 if (ctx->num_generation_data_overflows)
1966 add_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW,
1967 - sizeof(timestamp_t) * ctx->num_generation_data_overflows,
1967 + st_mult(sizeof(timestamp_t), ctx->num_generation_data_overflows),
1968 write_graph_chunk_generation_data_overflow);
1969 if (ctx->num_extra_edges)
1970 add_chunk(cf, GRAPH_CHUNKID_EXTRAEDGES,
1971 - 4 * ctx->num_extra_edges,
1971 + st_mult(4, ctx->num_extra_edges),
1972 write_graph_chunk_extra_edges);
1973 if (ctx->changed_paths) {
1974 add_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
1975 - sizeof(uint32_t) * ctx->commits.nr,
1975 + st_mult(sizeof(uint32_t), ctx->commits.nr),
1976 write_graph_chunk_bloom_indexes);
1977 add_chunk(cf, GRAPH_CHUNKID_BLOOMDATA,
1978 - sizeof(uint32_t) * 3
1979 - + ctx->total_bloom_filter_data_size,
1978 + st_add(sizeof(uint32_t) * 3,
1979 + ctx->total_bloom_filter_data_size),
1980 write_graph_chunk_bloom_data);
1981 }
1982 if (ctx->num_commit_graphs_after > 1)
1983 add_chunk(cf, GRAPH_CHUNKID_BASE,
1984 - hashsz * (ctx->num_commit_graphs_after - 1),
1984 + st_mult(hashsz, ctx->num_commit_graphs_after - 1),
1985 write_graph_chunk_base);
1986
1987 hashwrite_be32(f, GRAPH_SIGNATURE);
@@ -1999,7 +1999,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
1999 get_num_chunks(cf));
2000 ctx->progress = start_delayed_progress(
2001 progress_title.buf,
2002 - get_num_chunks(cf) * ctx->commits.nr);
2002 + st_mult(get_num_chunks(cf), ctx->commits.nr));
2003 }
2004
2005 write_chunkfile(cf, ctx);