[PATCH 2/9] Fix mmap leak caused by reading bad indexes.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If an index is corrupt, or is simply too new for us to understand,
we were leaking the mmap that held the entire content of the index.
This could be a considerable size on large projects, given that
the index is at least 24 bytes * nr_objects.

Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx>
---
 sha1_file.c |   25 ++++++++++++++++---------
 1 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index c13ef66..cfce7ac 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -430,8 +430,9 @@ void pack_report()
 		pack_mapped, peak_pack_mapped);
 }
 
-static int check_packed_git_idx(const char *path, unsigned long *idx_size_,
-				void **idx_map_)
+static int check_packed_git_idx(const char *path,
+	unsigned long *idx_size_,
+	void **idx_map_)
 {
 	void *idx_map;
 	uint32_t *index;
@@ -446,6 +447,10 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_,
 		return -1;
 	}
 	idx_size = st.st_size;
+	if (idx_size < 4 * 256 + 20 + 20) {
+		close(fd);
+		return error("index file %s is too small", path);
+	}
 	idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0);
 	close(fd);
 
@@ -453,25 +458,25 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_,
 	*idx_map_ = idx_map;
 	*idx_size_ = idx_size;
 
-	/* check index map */
-	if (idx_size < 4*256 + 20 + 20)
-		return error("index file %s is too small", path);
-
 	/* a future index format would start with this, as older git
 	 * binaries would fail the non-monotonic index check below.
 	 * give a nicer warning to the user if we can.
 	 */
-	if (index[0] == htonl(PACK_IDX_SIGNATURE))
+	if (index[0] == htonl(PACK_IDX_SIGNATURE)) {
+		munmap(idx_map, idx_size);
 		return error("index file %s is a newer version"
 			" and is not supported by this binary"
 			" (try upgrading GIT to a newer version)",
 			path);
+	}
 
 	nr = 0;
 	for (i = 0; i < 256; i++) {
 		unsigned int n = ntohl(index[i]);
-		if (n < nr)
+		if (n < nr) {
+			munmap(idx_map, idx_size);
 			return error("non-monotonic index %s", path);
+		}
 		nr = n;
 	}
 
@@ -482,8 +487,10 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_,
 	 *  - 20-byte SHA1 of the packfile
 	 *  - 20-byte SHA1 file checksum
 	 */
-	if (idx_size != 4*256 + nr * 24 + 20 + 20)
+	if (idx_size != 4*256 + nr * 24 + 20 + 20) {
+		munmap(idx_map, idx_size);
 		return error("wrong index file size in %s", path);
+	}
 
 	return 0;
 }
-- 
1.5.0.3.863.gf0989

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]