CVE-2018-8098 (published 2018-03-14T00:29Z)

Integer overflow in the index.c:read_entry() function while decompressing a compressed prefix length in libgit2 before v0.26.2 allows an attacker to cause a denial of service (out-of-bounds read) via a crafted repository index file.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 6.5, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-190
cwe_name: Integer Overflow or Wraparound
description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
extended_description: 
            
            
            
            
         
         

Fix information:
repo_url: https://github.com/libgit2/libgit2
commit_details: repo_url: https://github.com/libgit2/libgit2
author: Patrick Steinhardt
author_date: 2018-03-08 12:36:46+00:00
msg: index: error out on unreasonable prefix-compressed path lengths

When computing the complete path length from the encoded
prefix-compressed path, we end up just allocating the complete path
without ever checking what the encoded path length actually is. This can
easily lead to a denial of service by just encoding an unreasonable long
path name inside of the index. Git already enforces a maximum path
length of 4096 bytes. As we also have that enforcement ready in some
places, just make sure that the resulting path is smaller than
GIT_PATH_MAX.

Reported-by: Krishna Ram Prakash R <krp@gtux.in>
Reported-by: Vivek Parikh <viv0411.parikh@gmail.com>
repository: repo_url: https://github.com/libgit2/libgit2
repo_name: libgit2/libgit2
description: A cross-platform, linkable library implementation of Git that you can use in your application.
repo_language: C
owner: libgit2
file_changes: filename: index.c
change_type: ModificationType.MODIFY
diff: @@ -2379,6 +2379,10 @@ static int read_entry(
 
 		GITERR_CHECK_ALLOC_ADD(&path_len, prefix_len, suffix_len);
 		GITERR_CHECK_ALLOC_ADD(&path_len, path_len, 1);
+
+		if (path_len > GIT_PATH_MAX)
+			return index_error_invalid("unreasonable path length");
+
 		tmp_path = git__malloc(path_len);
 		GITERR_CHECK_ALLOC(tmp_path);
 

programming_language: C
repo_url: https://github.com/libgit2/libgit2
commit_details: repo_url: https://github.com/libgit2/libgit2
author: Patrick Steinhardt
author_date: 2018-03-08 12:00:27+00:00
msg: 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
5625d86b9 (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>
repository: repo_url: https://github.com/libgit2/libgit2
repo_name: libgit2/libgit2
description: A cross-platform, linkable library implementation of Git that you can use in your application.
repo_language: C
owner: libgit2
file_changes: filename: index.c
change_type: ModificationType.MODIFY
diff: @@ -2365,17 +2365,18 @@ static int read_entry(
 		entry_size = index_entry_size(path_length, 0, entry.flags);
 		entry.path = (char *)path_ptr;
 	} else {
-		size_t varint_len;
-		size_t strip_len = git_decode_varint((const unsigned char *)path_ptr,
-						     &varint_len);
-		size_t last_len = strlen(last);
-		size_t prefix_len = last_len - strip_len;
-		size_t suffix_len = strlen(path_ptr + varint_len);
-		size_t path_len;
-
-		if (varint_len == 0)
+		size_t varint_len, last_len, prefix_len, suffix_len, path_len;
+		uintmax_t strip_len;
+
+		strip_len = git_decode_varint((const unsigned char *)path_ptr, &varint_len);
+		last_len = strlen(last);
+
+		if (varint_len == 0 || last_len < strip_len)
 			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, path_len, 1);
 		tmp_path = git__malloc(path_len);

programming_language: C