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

1 messages from 2007-03-07 to 2007-03-07. Participants: Shawn O. Pearce.
Thread: https://gitlist.dev/t/7126

## Shawn O. Pearce, 2007-03-07 01:44

Subject: [PATCH 2/9] Fix mmap leak caused by reading bad indexes.
Message-ID: <20070307014411.GC26482@spearce.org>
URL: https://gitlist.dev/e/20070307014411.GC26482%40spearce.org

```
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@spearce.org>
---
 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

```
