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:
Junio C Hamano
2023-07-25 12:05:23 -07:00
5 changed files with 80 additions and 54 deletions

View File

@@ -184,7 +184,7 @@ int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
*/
(sizeof(off_t) <= 4))
return error("pack too large for current definition of off_t in %s", path);
p->crc_offset = 8 + 4 * 256 + nr * hashsz;
p->crc_offset = st_add(8 + 4 * 256, st_mult(nr, hashsz));
}
p->index_version = version;
@@ -1918,10 +1918,10 @@ int nth_packed_object_id(struct object_id *oid,
return -1;
index += 4 * 256;
if (p->index_version == 1) {
oidread(oid, index + (hashsz + 4) * n + 4);
oidread(oid, index + st_add(st_mult(hashsz + 4, n), 4));
} else {
index += 8;
oidread(oid, index + hashsz * n);
oidread(oid, index + st_mult(hashsz, n));
}
return 0;
}
@@ -1946,14 +1946,15 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
const unsigned int hashsz = the_hash_algo->rawsz;
index += 4 * 256;
if (p->index_version == 1) {
return ntohl(*((uint32_t *)(index + (hashsz + 4) * (size_t)n)));
return ntohl(*((uint32_t *)(index + st_mult(hashsz + 4, n))));
} else {
uint32_t off;
index += 8 + (size_t)p->num_objects * (hashsz + 4);
off = ntohl(*((uint32_t *)(index + 4 * n)));
index += st_add(8, st_mult(p->num_objects, hashsz + 4));
off = ntohl(*((uint32_t *)(index + st_mult(4, n))));
if (!(off & 0x80000000))
return off;
index += (size_t)p->num_objects * 4 + (off & 0x7fffffff) * 8;
index += st_add(st_mult(p->num_objects, 4),
st_mult(off & 0x7fffffff, 8));
check_pack_index_ptr(p, index);
return get_be64(index);
}