Commit 8b89f362a34fcccdf1c6c5f3445895b71d9c6d56

Patrick Steinhardt 2018-08-06T10:49:49

Merge pull request #4756 from pks-t/pks/v0.27.4 Release v0.27.4

diff --git a/.travis.yml b/.travis.yml
index a4c8e91..3a55e86 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,6 +21,7 @@ env:
   - OPTIONS="-DTHREADSAFE=OFF -DBUILD_EXAMPLES=ON -DENABLE_WERROR=ON"
 
 dist: trusty
+osx_image: xcode8.3
 sudo: false
 
 addons:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8b149ee..be62aa6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,18 @@
+v0.27.4
+-------
+
+This is a security release fixing out-of-bounds reads when
+processing smart-protocol "ng" packets.
+
+When parsing an "ng" packet, we keep track of both the current position
+as well as the remaining length of the packet itself. But instead of
+taking care not to exceed the length, we pass the current pointer's
+position to `strchr`, which will search for a certain character until
+hitting NUL. It is thus possible to create a crafted packet which
+doesn't contain a NUL byte to trigger an out-of-bounds read.
+
+The issue was discovered by the oss-fuzz project, issue 9406.
+
 v0.27.3
 -------
 
diff --git a/include/git2/version.h b/include/git2/version.h
index 8c2594f..7c42426 100644
--- a/include/git2/version.h
+++ b/include/git2/version.h
@@ -7,10 +7,10 @@
 #ifndef INCLUDE_git_version_h__
 #define INCLUDE_git_version_h__
 
-#define LIBGIT2_VERSION "0.27.3"
+#define LIBGIT2_VERSION "0.27.4"
 #define LIBGIT2_VER_MAJOR 0
 #define LIBGIT2_VER_MINOR 27
-#define LIBGIT2_VER_REVISION 3
+#define LIBGIT2_VER_REVISION 4
 #define LIBGIT2_VER_PATCH 0
 
 #define LIBGIT2_SOVERSION 27
diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c
index a661dfe..d10d6c6 100644
--- a/src/transports/smart_pkt.c
+++ b/src/transports/smart_pkt.c
@@ -299,8 +299,11 @@ static int ng_pkt(git_pkt **out, const char *line, size_t len)
 	pkt->ref = NULL;
 	pkt->type = GIT_PKT_NG;
 
+	if (len < 3)
+		goto out_err;
 	line += 3; /* skip "ng " */
-	if (!(ptr = strchr(line, ' ')))
+	len -= 3;
+	if (!(ptr = memchr(line, ' ', len)))
 		goto out_err;
 	len = ptr - line;
 
@@ -311,8 +314,11 @@ static int ng_pkt(git_pkt **out, const char *line, size_t len)
 	memcpy(pkt->ref, line, len);
 	pkt->ref[len] = '\0';
 
+	if (len < 1)
+		goto out_err;
 	line = ptr + 1;
-	if (!(ptr = strchr(line, '\n')))
+	len -= 1;
+	if (!(ptr = memchr(line, '\n', len)))
 		goto out_err;
 	len = ptr - line;