diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2022-04-10 09:45:51 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-10 09:45:51 -0400 |
commit | 7e8d9be0cc168c22cbaf1116bd5b27c0a6076565 (patch) | |
tree | 7822442e64dee5717d4524404e624fce6e1621d0 | |
parent | 606afeda5a0ff4d7ccb1476428682e078364c24d (diff) | |
parent | 33b1d3fd62c3702ff6cc85c95dc01f372253851e (diff) | |
download | libgit2-7e8d9be0cc168c22cbaf1116bd5b27c0a6076565.tar.gz |
Merge pull request #6260 from lhchavez/midx-fix-ub
midx: Fix an undefined behavior (left-shift signed overflow)
-rw-r--r-- | fuzzers/corpora/midx/666a779eed16847c6930a71c0547a34e52db409e | bin | 0 -> 62 bytes | |||
-rw-r--r-- | src/libgit2/midx.c | 11 |
2 files changed, 8 insertions, 3 deletions
diff --git a/fuzzers/corpora/midx/666a779eed16847c6930a71c0547a34e52db409e b/fuzzers/corpora/midx/666a779eed16847c6930a71c0547a34e52db409e Binary files differnew file mode 100644 index 000000000..ed9e0d07a --- /dev/null +++ b/fuzzers/corpora/midx/666a779eed16847c6930a71c0547a34e52db409e diff --git a/src/libgit2/midx.c b/src/libgit2/midx.c index eb99e7373..0092601f6 100644 --- a/src/libgit2/midx.c +++ b/src/libgit2/midx.c @@ -225,8 +225,13 @@ int git_midx_parse( chunk_hdr = data + sizeof(struct git_midx_header); last_chunk = NULL; for (i = 0; i < hdr->chunks; ++i, chunk_hdr += 12) { - chunk_offset = ((off64_t)ntohl(*((uint32_t *)(chunk_hdr + 4)))) << 32 | - ((off64_t)ntohl(*((uint32_t *)(chunk_hdr + 8)))); + uint32_t chunk_id = ntohl(*((uint32_t *)(chunk_hdr + 0))); + uint64_t high_offset = ((uint64_t)ntohl(*((uint32_t *)(chunk_hdr + 4)))) & 0xffffffffu; + uint64_t low_offset = ((uint64_t)ntohl(*((uint32_t *)(chunk_hdr + 8)))) & 0xffffffffu; + + if (high_offset >= INT32_MAX) + return midx_error("chunk offset out of range"); + chunk_offset = (off64_t)(high_offset << 32 | low_offset); if (chunk_offset < last_chunk_offset) return midx_error("chunks are non-monotonic"); if (chunk_offset >= trailer_offset) @@ -235,7 +240,7 @@ int git_midx_parse( last_chunk->length = (size_t)(chunk_offset - last_chunk_offset); last_chunk_offset = chunk_offset; - switch (ntohl(*((uint32_t *)(chunk_hdr + 0)))) { + switch (chunk_id) { case MIDX_PACKFILE_NAMES_ID: chunk_packfile_names.offset = last_chunk_offset; last_chunk = &chunk_packfile_names; |