Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bloom.c24
-rw-r--r--commit-graph.c10
-rw-r--r--commit-graph.h1
-rwxr-xr-xt/t4216-log-bloom.sh28
4 files changed, 63 insertions, 0 deletions
diff --git a/bloom.c b/bloom.c
index aef6b5fea2..61abad7f8c 100644
--- a/bloom.c
+++ b/bloom.c
@@ -29,6 +29,26 @@ static inline unsigned char get_bitmask(uint32_t pos)
return ((unsigned char)1) << (pos & (BITS_PER_WORD - 1));
}
+static int check_bloom_offset(struct commit_graph *g, uint32_t pos,
+ uint32_t offset)
+{
+ /*
+ * Note that we allow offsets equal to the data size, which would set
+ * our pointers at one past the end of the chunk memory. This is
+ * necessary because the on-disk index points to the end of the
+ * entries (so we can compute size by comparing adjacent ones). And
+ * naturally the final entry's end is one-past-the-end of the chunk.
+ */
+ if (offset <= g->chunk_bloom_data_size - BLOOMDATA_CHUNK_HEADER_SIZE)
+ return 0;
+
+ warning("ignoring out-of-range offset (%"PRIuMAX") for changed-path"
+ " filter at pos %"PRIuMAX" of %s (chunk size: %"PRIuMAX")",
+ (uintmax_t)offset, (uintmax_t)pos,
+ g->filename, (uintmax_t)g->chunk_bloom_data_size);
+ return -1;
+}
+
static int load_bloom_filter_from_graph(struct commit_graph *g,
struct bloom_filter *filter,
uint32_t graph_pos)
@@ -51,6 +71,10 @@ static int load_bloom_filter_from_graph(struct commit_graph *g,
else
start_index = 0;
+ if (check_bloom_offset(g, lex_pos, end_index) < 0 ||
+ check_bloom_offset(g, lex_pos - 1, start_index) < 0)
+ return 0;
+
filter->len = end_index - start_index;
filter->data = (unsigned char *)(g->chunk_bloom_data +
sizeof(unsigned char) * start_index +
diff --git a/commit-graph.c b/commit-graph.c
index f446e76c28..f7a42be6d0 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -365,7 +365,17 @@ static int graph_read_bloom_data(const unsigned char *chunk_start,
{
struct commit_graph *g = data;
uint32_t hash_version;
+
+ if (chunk_size < BLOOMDATA_CHUNK_HEADER_SIZE) {
+ warning("ignoring too-small changed-path chunk"
+ " (%"PRIuMAX" < %"PRIuMAX") in commit-graph file",
+ (uintmax_t)chunk_size,
+ (uintmax_t)BLOOMDATA_CHUNK_HEADER_SIZE);
+ return -1;
+ }
+
g->chunk_bloom_data = chunk_start;
+ g->chunk_bloom_data_size = chunk_size;
hash_version = get_be32(chunk_start);
if (hash_version != 1)
diff --git a/commit-graph.h b/commit-graph.h
index b373f15802..c6870274c5 100644
--- a/commit-graph.h
+++ b/commit-graph.h
@@ -101,6 +101,7 @@ struct commit_graph {
size_t chunk_base_graphs_size;
const unsigned char *chunk_bloom_indexes;
const unsigned char *chunk_bloom_data;
+ size_t chunk_bloom_data_size;
struct topo_level_slab *topo_levels;
struct bloom_filter_settings *bloom_filter_settings;
diff --git a/t/t4216-log-bloom.sh b/t/t4216-log-bloom.sh
index fa9d32facf..7a727bcddd 100755
--- a/t/t4216-log-bloom.sh
+++ b/t/t4216-log-bloom.sh
@@ -5,6 +5,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-chunk.sh
GIT_TEST_COMMIT_GRAPH=0
GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0
@@ -404,4 +405,31 @@ test_expect_success 'Bloom generation backfills empty commits' '
)
'
+corrupt_graph () {
+ graph=.git/objects/info/commit-graph &&
+ test_when_finished "rm -rf $graph" &&
+ git commit-graph write --reachable --changed-paths &&
+ corrupt_chunk_file $graph "$@"
+}
+
+check_corrupt_graph () {
+ corrupt_graph "$@" &&
+ git -c core.commitGraph=false log -- A/B/file2 >expect.out &&
+ git -c core.commitGraph=true log -- A/B/file2 >out 2>err &&
+ test_cmp expect.out out
+}
+
+test_expect_success 'Bloom reader notices too-small data chunk' '
+ check_corrupt_graph BDAT clear 00000000 &&
+ echo "warning: ignoring too-small changed-path chunk" \
+ "(4 < 12) in commit-graph file" >expect.err &&
+ test_cmp expect.err err
+'
+
+test_expect_success 'Bloom reader notices out-of-bounds filter offsets' '
+ check_corrupt_graph BIDX 12 FFFFFFFF &&
+ # use grep to avoid depending on exact chunk size
+ grep "warning: ignoring out-of-range offset (4294967295) for changed-path filter at pos 3 of .git/objects/info/commit-graph" err
+'
+
test_done