Git fork

commit-graph: detect out-of-order BIDX offsets

The BIDX chunk tells us the offsets at which each commit's Bloom filters
can be found in the BDAT chunk. We compute the length of each filter by
checking the offsets of neighbors and subtracting them.

If the offsets are out of order, then we'll get a negative length, which
we then store as a very large unsigned value. This can cause us to read
out-of-bounds memory, as we access the hash data modulo "filter->len *
BITS_PER_WORD".

We can easily detect this case when loading the individual filters.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Jeff King and committed by
Junio C Hamano
12192a9d 581e0f8b

+23
+10
bloom.c
··· 75 75 check_bloom_offset(g, lex_pos - 1, start_index) < 0) 76 76 return 0; 77 77 78 + if (end_index < start_index) { 79 + warning("ignoring decreasing changed-path index offsets" 80 + " (%"PRIuMAX" > %"PRIuMAX") for positions" 81 + " %"PRIuMAX" and %"PRIuMAX" of %s", 82 + (uintmax_t)start_index, (uintmax_t)end_index, 83 + (uintmax_t)(lex_pos-1), (uintmax_t)lex_pos, 84 + g->filename); 85 + return 0; 86 + } 87 + 78 88 filter->len = end_index - start_index; 79 89 filter->data = (unsigned char *)(g->chunk_bloom_data + 80 90 sizeof(unsigned char) * start_index +
+13
t/t4216-log-bloom.sh
··· 441 441 test_cmp expect.err err 442 442 ' 443 443 444 + test_expect_success 'Bloom reader notices out-of-order index offsets' ' 445 + # we do not know any real offsets, but we can pick 446 + # something plausible; we should not get to the point of 447 + # actually reading from the bogus offsets anyway. 448 + corrupt_graph BIDX 4 0000000c00000005 && 449 + echo "warning: ignoring decreasing changed-path index offsets" \ 450 + "(12 > 5) for positions 1 and 2 of .git/objects/info/commit-graph" >expect.err && 451 + git -c core.commitGraph=false log -- A/B/file2 >expect.out && 452 + git -c core.commitGraph=true log -- A/B/file2 >out 2>err && 453 + test_cmp expect.out out && 454 + test_cmp expect.err err 455 + ' 456 + 444 457 test_done