]> git.ipfire.org Git - thirdparty/git.git/commitdiff
midx: check size of revindex chunk
authorJeff King <peff@peff.net>
Mon, 9 Oct 2023 21:05:33 +0000 (17:05 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Oct 2023 22:55:01 +0000 (15:55 -0700)
When we load a revindex from disk, we check the size of the file
compared to the number of objects we expect it to have. But when we use
a RIDX chunk stored directly in the midx, we just access the memory
directly. This can lead to out-of-bounds memory access for a corrupted
or malicious multi-pack-index file.

We can catch this by recording the RIDX chunk size, and then checking it
against the expected size when we "load" the revindex. Note that this
check is much simpler than the one that load_revindex_from_disk() does,
because we just have the data array with no header (so we do not need
to account for the header size, and nor do we need to bother validating
the header values).

The test confirms both that we catch this case, and that we continue the
process (the revindex is required to use the midx bitmaps, but we
fallback to a non-bitmap traversal).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
midx.c
midx.h
pack-revindex.c
t/t5319-multi-pack-index.sh

diff --git a/midx.c b/midx.c
index 3e768d0df079b79339b61e590d6cdd50f5bdb502..2f3863c936a4c1c9035f90ae28b73887cf8f24b2 100644 (file)
--- a/midx.c
+++ b/midx.c
@@ -184,7 +184,8 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
                   &m->chunk_large_offsets_len);
 
        if (git_env_bool("GIT_TEST_MIDX_READ_RIDX", 1))
-               pair_chunk_unsafe(cf, MIDX_CHUNKID_REVINDEX, &m->chunk_revindex);
+               pair_chunk(cf, MIDX_CHUNKID_REVINDEX, &m->chunk_revindex,
+                          &m->chunk_revindex_len);
 
        CALLOC_ARRAY(m->pack_names, m->num_packs);
        CALLOC_ARRAY(m->packs, m->num_packs);
diff --git a/midx.h b/midx.h
index e8e8884d16b08be6dbb088dc01229a314db8fe39..a5d98919c857b812789f44d86fb6ad13fb7e0560 100644 (file)
--- a/midx.h
+++ b/midx.h
@@ -39,6 +39,7 @@ struct multi_pack_index {
        const unsigned char *chunk_large_offsets;
        size_t chunk_large_offsets_len;
        const unsigned char *chunk_revindex;
+       size_t chunk_revindex_len;
 
        const char **pack_names;
        struct packed_git **packs;
index 7fffcad9125610cb05a5823b03b86d3e28eeabdb..6d8fd3645a7350ee30e0a4740c5b4aca1c610a79 100644 (file)
@@ -343,6 +343,17 @@ int verify_pack_revindex(struct packed_git *p)
        return res;
 }
 
+static int can_use_midx_ridx_chunk(struct multi_pack_index *m)
+{
+       if (!m->chunk_revindex)
+               return 0;
+       if (m->chunk_revindex_len != st_mult(sizeof(uint32_t), m->num_objects)) {
+               error(_("multi-pack-index reverse-index chunk is the wrong size"));
+               return 0;
+       }
+       return 1;
+}
+
 int load_midx_revindex(struct multi_pack_index *m)
 {
        struct strbuf revindex_name = STRBUF_INIT;
@@ -351,7 +362,7 @@ int load_midx_revindex(struct multi_pack_index *m)
        if (m->revindex_data)
                return 0;
 
-       if (m->chunk_revindex) {
+       if (can_use_midx_ridx_chunk(m)) {
                /*
                 * If the MIDX `m` has a `RIDX` chunk, then use its contents for
                 * the reverse index instead of trying to load a separate `.rev`
index 16050f39d997de4694c54c334794b1a40f60cd9c..2a11dd1af6a7c20c7206b69471667a598f811c05 100755 (executable)
@@ -1138,4 +1138,21 @@ test_expect_success 'reader bounds-checks large offset table' '
        )
 '
 
+test_expect_success 'reader notices too-small revindex chunk' '
+       # We only get a revindex with bitmaps (and likewise only
+       # load it when they are asked for).
+       test_config repack.writeBitmaps true &&
+       corrupt_chunk RIDX clear 00000000 &&
+       git -c core.multipackIndex=false rev-list \
+               --all --use-bitmap-index >expect.out &&
+       git -c core.multipackIndex=true rev-list \
+               --all --use-bitmap-index >out 2>err &&
+       test_cmp expect.out out &&
+       cat >expect.err <<-\EOF &&
+       error: multi-pack-index reverse-index chunk is the wrong size
+       warning: multi-pack bitmap is missing required reverse index
+       EOF
+       test_cmp expect.err err
+'
+
 test_done