Commit a3cd5e941b017edbf0fd739c332474945d69f789

lhchavez 2017-12-06T03:03:18

libFuzzer: Fix missing trailer crash This change fixes an invalid memory access when the trailer is missing / corrupt. Found using libFuzzer.

diff --git a/src/indexer.c b/src/indexer.c
index bd091d7..fff60a0 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -950,6 +950,10 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
 		giterr_set(GITERR_INDEXER, "unexpected data at the end of the pack");
 		return -1;
 	}
+	if (idx->off + 20 > idx->pack->mwf.size) {
+		giterr_set(GITERR_INDEXER, "missing trailer at the end of the pack");
+		return -1;
+	}
 
 	packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ, &left);
 	if (packfile_trailer == NULL) {
diff --git a/tests/pack/indexer.c b/tests/pack/indexer.c
index a28ee3e..4d2d9f6 100644
--- a/tests/pack/indexer.c
+++ b/tests/pack/indexer.c
@@ -87,6 +87,23 @@ void test_pack_indexer__leaky(void)
 	git_indexer_free(idx);
 }
 
+void test_pack_indexer__missing_trailer(void)
+{
+	git_indexer *idx = 0;
+	git_transfer_progress stats = { 0 };
+
+	cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
+	/* Truncate a valid packfile */
+	cl_git_pass(git_indexer_append(
+		idx, out_of_order_pack, out_of_order_pack_len - 20, &stats));
+	cl_git_fail(git_indexer_commit(idx, &stats));
+
+	cl_assert(giterr_last() != NULL);
+	cl_assert_equal_i(giterr_last()->klass, GITERR_INDEXER);
+
+	git_indexer_free(idx);
+}
+
 void test_pack_indexer__fix_thin(void)
 {
 	git_indexer *idx = NULL;