mirror of
https://github.com/git/git.git
synced 2025-12-12 20:36:24 +01:00
Merge branch 'tb/object-access-overflow-protection'
Various offset computation in the code that accesses the packfiles and other data in the object layer has been hardened against arithmetic overflow, especially on 32-bit systems. * tb/object-access-overflow-protection: commit-graph.c: prevent overflow in `verify_commit_graph()` commit-graph.c: prevent overflow in `write_commit_graph()` commit-graph.c: prevent overflow in `merge_commit_graph()` commit-graph.c: prevent overflow in `split_graph_merge_strategy()` commit-graph.c: prevent overflow in `load_tree_for_commit()` commit-graph.c: prevent overflow in `fill_commit_in_graph()` commit-graph.c: prevent overflow in `fill_commit_graph_info()` commit-graph.c: prevent overflow in `load_oid_from_graph()` commit-graph.c: prevent overflow in add_graph_to_chain() commit-graph.c: prevent overflow in `write_commit_graph_file()` pack-bitmap.c: ensure that eindex lookups don't overflow midx.c: prevent overflow in `fill_included_packs_batch()` midx.c: prevent overflow in `write_midx_internal()` midx.c: store `nr`, `alloc` variables as `size_t`'s midx.c: prevent overflow in `nth_midxed_offset()` midx.c: prevent overflow in `nth_midxed_object_oid()` midx.c: use `size_t`'s for fanout nr and alloc packfile.c: use checked arithmetic in `nth_packed_object_offset()` packfile.c: prevent overflow in `load_idx()` packfile.c: prevent overflow in `nth_packed_object_id()`
This commit is contained in:
42
midx.c
42
midx.c
@@ -253,7 +253,7 @@ struct object_id *nth_midxed_object_oid(struct object_id *oid,
|
||||
if (n >= m->num_objects)
|
||||
return NULL;
|
||||
|
||||
oidread(oid, m->chunk_oid_lookup + m->hash_len * n);
|
||||
oidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n));
|
||||
return oid;
|
||||
}
|
||||
|
||||
@@ -270,7 +270,8 @@ off_t nth_midxed_offset(struct multi_pack_index *m, uint32_t pos)
|
||||
die(_("multi-pack-index stores a 64-bit offset, but off_t is too small"));
|
||||
|
||||
offset32 ^= MIDX_LARGE_OFFSET_NEEDED;
|
||||
return get_be64(m->chunk_large_offsets + sizeof(uint64_t) * offset32);
|
||||
return get_be64(m->chunk_large_offsets +
|
||||
st_mult(sizeof(uint64_t), offset32));
|
||||
}
|
||||
|
||||
return offset32;
|
||||
@@ -444,14 +445,14 @@ static int idx_or_pack_name_cmp(const void *_va, const void *_vb)
|
||||
|
||||
struct write_midx_context {
|
||||
struct pack_info *info;
|
||||
uint32_t nr;
|
||||
uint32_t alloc;
|
||||
size_t nr;
|
||||
size_t alloc;
|
||||
struct multi_pack_index *m;
|
||||
struct progress *progress;
|
||||
unsigned pack_paths_checked;
|
||||
|
||||
struct pack_midx_entry *entries;
|
||||
uint32_t entries_nr;
|
||||
size_t entries_nr;
|
||||
|
||||
uint32_t *pack_perm;
|
||||
uint32_t *pack_order;
|
||||
@@ -583,12 +584,14 @@ static void fill_pack_entry(uint32_t pack_int_id,
|
||||
|
||||
struct midx_fanout {
|
||||
struct pack_midx_entry *entries;
|
||||
uint32_t nr;
|
||||
uint32_t alloc;
|
||||
size_t nr, alloc;
|
||||
};
|
||||
|
||||
static void midx_fanout_grow(struct midx_fanout *fanout, uint32_t nr)
|
||||
static void midx_fanout_grow(struct midx_fanout *fanout, size_t nr)
|
||||
{
|
||||
if (nr < fanout->nr)
|
||||
BUG("negative growth in midx_fanout_grow() (%"PRIuMAX" < %"PRIuMAX")",
|
||||
(uintmax_t)nr, (uintmax_t)fanout->nr);
|
||||
ALLOC_GROW(fanout->entries, nr, fanout->alloc);
|
||||
}
|
||||
|
||||
@@ -667,17 +670,18 @@ static void midx_fanout_add_pack_fanout(struct midx_fanout *fanout,
|
||||
static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
|
||||
struct pack_info *info,
|
||||
uint32_t nr_packs,
|
||||
uint32_t *nr_objects,
|
||||
size_t *nr_objects,
|
||||
int preferred_pack)
|
||||
{
|
||||
uint32_t cur_fanout, cur_pack, cur_object;
|
||||
uint32_t alloc_objects, total_objects = 0;
|
||||
size_t alloc_objects, total_objects = 0;
|
||||
struct midx_fanout fanout = { 0 };
|
||||
struct pack_midx_entry *deduplicated_entries = NULL;
|
||||
uint32_t start_pack = m ? m->num_packs : 0;
|
||||
|
||||
for (cur_pack = start_pack; cur_pack < nr_packs; cur_pack++)
|
||||
total_objects += info[cur_pack].p->num_objects;
|
||||
total_objects = st_add(total_objects,
|
||||
info[cur_pack].p->num_objects);
|
||||
|
||||
/*
|
||||
* As we de-duplicate by fanout value, we expect the fanout
|
||||
@@ -720,7 +724,8 @@ static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
|
||||
&fanout.entries[cur_object].oid))
|
||||
continue;
|
||||
|
||||
ALLOC_GROW(deduplicated_entries, *nr_objects + 1, alloc_objects);
|
||||
ALLOC_GROW(deduplicated_entries, st_add(*nr_objects, 1),
|
||||
alloc_objects);
|
||||
memcpy(&deduplicated_entries[*nr_objects],
|
||||
&fanout.entries[cur_object],
|
||||
sizeof(struct pack_midx_entry));
|
||||
@@ -1495,21 +1500,22 @@ static int write_midx_internal(const char *object_dir,
|
||||
add_chunk(cf, MIDX_CHUNKID_OIDFANOUT, MIDX_CHUNK_FANOUT_SIZE,
|
||||
write_midx_oid_fanout);
|
||||
add_chunk(cf, MIDX_CHUNKID_OIDLOOKUP,
|
||||
(size_t)ctx.entries_nr * the_hash_algo->rawsz,
|
||||
st_mult(ctx.entries_nr, the_hash_algo->rawsz),
|
||||
write_midx_oid_lookup);
|
||||
add_chunk(cf, MIDX_CHUNKID_OBJECTOFFSETS,
|
||||
(size_t)ctx.entries_nr * MIDX_CHUNK_OFFSET_WIDTH,
|
||||
st_mult(ctx.entries_nr, MIDX_CHUNK_OFFSET_WIDTH),
|
||||
write_midx_object_offsets);
|
||||
|
||||
if (ctx.large_offsets_needed)
|
||||
add_chunk(cf, MIDX_CHUNKID_LARGEOFFSETS,
|
||||
(size_t)ctx.num_large_offsets * MIDX_CHUNK_LARGE_OFFSET_WIDTH,
|
||||
st_mult(ctx.num_large_offsets,
|
||||
MIDX_CHUNK_LARGE_OFFSET_WIDTH),
|
||||
write_midx_large_offsets);
|
||||
|
||||
if (flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP)) {
|
||||
ctx.pack_order = midx_pack_order(&ctx);
|
||||
add_chunk(cf, MIDX_CHUNKID_REVINDEX,
|
||||
ctx.entries_nr * sizeof(uint32_t),
|
||||
st_mult(ctx.entries_nr, sizeof(uint32_t)),
|
||||
write_midx_revindex);
|
||||
}
|
||||
|
||||
@@ -1987,8 +1993,8 @@ static int fill_included_packs_batch(struct repository *r,
|
||||
if (open_pack_index(p) || !p->num_objects)
|
||||
continue;
|
||||
|
||||
expected_size = (size_t)(p->pack_size
|
||||
* pack_info[i].referenced_objects);
|
||||
expected_size = st_mult(p->pack_size,
|
||||
pack_info[i].referenced_objects);
|
||||
expected_size /= p->num_objects;
|
||||
|
||||
if (expected_size >= batch_size)
|
||||
|
||||
Reference in New Issue
Block a user