midx: use 64-bit multiplication for chunk sizes
When calculating the sizes of certain chunks, we should use 64-bit multiplication always. This allows us to properly predict the chunk sizes without risk of overflow. Other possible overflows were discovered by evaluating each multiplication in midx.c and ensuring that at least one side of the operator was of type size_t or off_t. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Derrick Stolee committed
Feb 18, 2021 at 14:07 UTC
329fac3a366244ceac599ab63cd338bcc6a1dcb4
1 file changed
+6
-5
midx.c
+6
-5
@@ -244,7 +244,7 @@ static off_t nth_midxed_offset(struct multi_pack_index *m, uint32_t pos)
244
const unsigned char *offset_data;
245
uint32_t offset32;
246
247
- offset_data = m->chunk_object_offsets + pos * MIDX_CHUNK_OFFSET_WIDTH;
247
+ offset_data = m->chunk_object_offsets + (off_t)pos * MIDX_CHUNK_OFFSET_WIDTH;
248
offset32 = get_be32(offset_data + sizeof(uint32_t));
249
250
if (m->chunk_large_offsets && offset32 & MIDX_LARGE_OFFSET_NEEDED) {
@@ -260,7 +260,8 @@ static off_t nth_midxed_offset(struct multi_pack_index *m, uint32_t pos)
260
261
static uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos)
262
{
263
- return get_be32(m->chunk_object_offsets + pos * MIDX_CHUNK_OFFSET_WIDTH);
263
+ return get_be32(m->chunk_object_offsets +
264
+ (off_t)pos * MIDX_CHUNK_OFFSET_WIDTH);
265
}
266
267
static int nth_midxed_pack_entry(struct repository *r,
@@ -912,15 +913,15 @@ static int write_midx_internal(const char *object_dir, struct multi_pack_index *
913
add_chunk(cf, MIDX_CHUNKID_OIDFANOUT, MIDX_CHUNK_FANOUT_SIZE,
914
write_midx_oid_fanout);
915
add_chunk(cf, MIDX_CHUNKID_OIDLOOKUP,
915
- ctx.entries_nr * the_hash_algo->rawsz,
916
+ (size_t)ctx.entries_nr * the_hash_algo->rawsz,
917
write_midx_oid_lookup);
918
add_chunk(cf, MIDX_CHUNKID_OBJECTOFFSETS,
918
- ctx.entries_nr * MIDX_CHUNK_OFFSET_WIDTH,
919
+ (size_t)ctx.entries_nr * MIDX_CHUNK_OFFSET_WIDTH,
920
write_midx_object_offsets);
921
922
if (ctx.large_offsets_needed)
923
add_chunk(cf, MIDX_CHUNKID_LARGEOFFSETS,
923
- ctx.num_large_offsets * MIDX_CHUNK_LARGE_OFFSET_WIDTH,
924
+ (size_t)ctx.num_large_offsets * MIDX_CHUNK_LARGE_OFFSET_WIDTH,
925
write_midx_large_offsets);
926
927
write_midx_header(f, get_num_chunks(cf), ctx.nr - dropped_packs);