Commit 6ddd286e by Patrick Steinhardt

index: fix out-of-bounds read with invalid index entry prefix length

The index format in version 4 has prefix-compressed entries, where every
index entry can compress its path by using a path prefix of the previous
entry. Since implmenting support for this index format version in commit
5625d86b (index: support index v4, 2016-05-17), though, we do not
correctly verify that the prefix length that we want to reuse is
actually smaller or equal to the amount of characters than the length of
the previous index entry's path. This can lead to a an integer underflow
and subsequently to an out-of-bounds read.

Fix this by verifying that the prefix is actually smaller than the
previous entry's path length.

Reported-by: Krishna Ram Prakash R <krp@gtux.in>
Reported-by: Vivek Parikh <viv0411.parikh@gmail.com>
parent b6756821
...@@ -2361,17 +2361,18 @@ static int read_entry( ...@@ -2361,17 +2361,18 @@ static int read_entry(
entry_size = index_entry_size(path_length, 0, entry.flags); entry_size = index_entry_size(path_length, 0, entry.flags);
entry.path = (char *)path_ptr; entry.path = (char *)path_ptr;
} else { } else {
size_t varint_len; size_t varint_len, last_len, prefix_len, suffix_len, path_len;
size_t strip_len = git_decode_varint((const unsigned char *)path_ptr, uintmax_t strip_len;
&varint_len);
size_t last_len = strlen(last); strip_len = git_decode_varint((const unsigned char *)path_ptr, &varint_len);
size_t prefix_len = last_len - strip_len; last_len = strlen(last);
size_t suffix_len = strlen(path_ptr + varint_len);
size_t path_len; if (varint_len == 0 || last_len < strip_len)
if (varint_len == 0)
return index_error_invalid("incorrect prefix length"); return index_error_invalid("incorrect prefix length");
prefix_len = last_len - strip_len;
suffix_len = strlen(path_ptr + varint_len);
GITERR_CHECK_ALLOC_ADD(&path_len, prefix_len, suffix_len); GITERR_CHECK_ALLOC_ADD(&path_len, prefix_len, suffix_len);
GITERR_CHECK_ALLOC_ADD(&path_len, path_len, 1); GITERR_CHECK_ALLOC_ADD(&path_len, path_len, 1);
tmp_path = git__malloc(path_len); tmp_path = git__malloc(path_len);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment